当先锋百科网

首页 1 2 3 4 5 6 7

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 15296    Accepted Submission(s): 4629


Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)

Output
输出 一行有两个数, 最短距离及其花费。

Sample Input
  
3 2 1 2 5 6 2 3 4 5 1 3 0 0

Sample Output
  
9 11
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int map[2][1010][1010],vis[1010],dis[2][1010];
int n,m,s,t;
int getnext(){int i,u=-1,t=inf;int temp=inf;for(i=1;i<=n;++i){if(!vis[i]&&(dis[0][i]<temp||(dis[0][i]==temp&&dis[1][i]<t))){t=dis[1][i];temp=dis[0][i];u=i;}}return u;
}
void dijkstra(){int u=s,temp,i,j,k;memset(vis,0,sizeof(vis));while(u!=-1){for(i=1;i<=n;++i){temp=dis[0][u]+map[0][u][i];if(temp<dis[0][i]){dis[0][i]=temp;dis[1][i]=dis[1][u]+map[1][u][i];}else if(temp==dis[0][i]){if(dis[1][u]+map[1][u][i]<dis[1][i]){dis[1][i]=dis[1][u]+map[1][u][i];}}}vis[u]=1;if(u==t){printf("%d %d\n",dis[0][t],dis[1][t]);break;}u=getnext();}
}
int main()
{int i,j,a,b,c,d;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0)break;memset(dis,0x3f,sizeof(dis));memset(map,0x3f,sizeof(map));for(j=0;j<m;++j){scanf("%d%d%d%d",&a,&b,&c,&d);if(c<map[0][a][b]||(map[0][a][b]==c&&map[1][a][b]>d)){map[0][a][b]=map[0][b][a]=c;map[1][a][b]=map[1][b][a]=d;}}scanf("%d%d",&s,&t);dis[0][s]=dis[1][s]=0;dijkstra();}return 0;
}