PAT 1030 Travel Plan   dijkstra算法+双最短条件+保存最短路_i++


题意:

给出一个无向图。求出起点到终点的最优路,并输出所经过的点。

最优: 距离最短,若距离相等则权重最短。


思路:

1.注意这是个无向图!!

2.用vector存储经过的点。记得起点也要存储。

//628K  94MS
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<map>
using namespace std;
#define INF 99999999
#define M 700
int dis[M][M],cost[M][M];
int n;
int d[M],c[M],vis[M];
vector<int> vec[M];
void dj(int s,int e)
{
int select,i,j;
int minc,mind;
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
{
d[i]=c[i]=INF;
}
d[s] = 0;
c[s] = 0;
vec[s].push_back(s);
for(i = 0;i< n;i++)
{
minc = INF;
mind = INF;
select = -1;
for(j=0;j<n;j++)
{
if(vis[j]==0)
{
if(d[j] < mind)
{
mind = d[j];
minc = c[j];
select = j;
}
else if(d[j]==mind && c[j] < minc)
{
mind = d[j];
minc = c[j];
select = j;
}
}
}

if(select == -1)
break;

vis[select] = 1;
for(j=0;j<n;j++)
{
if(vis[j])
continue;
if(d[select]+dis[select][j] < d[j])
{
d[j] = d[select]+dis[select][j];
c[j] = c[select] + cost[select][j];
vec[j] = vec[select];
vec[j].push_back(j);
}
else if(d[select]+dis[select][j] == d[j] && c[select]+cost[select][j] < c[j])
{
d[j] = d[select]+dis[select][j];
c[j] = c[select] + cost[select][j];
vec[j] = vec[select];
vec[j].push_back(j);
}
}
}

for(i=0;i<vec[e].size();i++)
{
printf("%d ",vec[e][i]);
}
printf("%d %d\n",d[e],c[e]);
}

int main(){

int m,s,e;
int c1,c2,d,c;
int i ,j;
scanf("%d%d%d%d\n",&n,&m,&s,&e);
for(i=0;i<n;i++)
for( j=0;j<n;j++)
{
if(i==j)
{
dis[i][j]=0;
cost[i][j]=0;
}
else
{
dis[i][j]=INF;
cost[i][j]=INF;
}
}

for(i=0;i<m;i++)
{
scanf("%d%d%d%d",&c1,&c2,&d,&c);
dis[c1][c2]=dis[c2][c1]=d;
cost[c1][c2]=cost[c2][c1]=c;
}
dj(s,e);
return 0;
}