hdu 3790(最短路径问题 SPFA算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790
最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17893 Accepted Submission(s): 5355
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)
(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 <vector> #include <iostream> #include <queue> #define INF 0xfffffff using namespace std; const int maxn = 1010; struct node{ int v,len,value; node(int v=0,int len=0,int value =0):v(v),len(len),value(value){} }; vector<node >G[maxn]; bool inqueue[maxn]; int minDist[maxn]; int minValue[maxn]; int n,m; void SPFA(int st,int end){ queue<node>Q; minDist[st]=0; minValue[st]=0; Q.push(node(st,0,0)); inqueue[st]=1; while(!Q.empty()){ node V=Q.front(); int v1=V.v; Q.pop(); inqueue[v1]=false; for(int i=0;i<G[v1].size();i++){ int v2=G[v1][i].v; int len=G[v1][i].len; int value=G[v1][i].value; if(minDist[v2]>minDist[v1]+len){ minDist[v2]=minDist[v1]+len; minValue[v2]=minValue[v1]+value; if(!inqueue[v2]){ Q.push(G[v1][i]); inqueue[v2]=true; } } else if(minDist[v2]==minDist[v1]+len){ if(minValue[v2]>minValue[v1]+value){ minValue[v2]=minValue[v1]+value; } if(!inqueue[v2]){ Q.push(G[v1][i]); inqueue[v2]=true; } } } } } void init(){ for(int i=0;i<maxn;i++) { G[i].clear(); inqueue[i]=false; minDist[i]=INF; minValue[i]=INF; } } int main(){ while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){ init(); int v1,v2,len,value; for(int i=0;i<m;i++){ scanf("%d%d%d%d",&v1,&v2,&len,&value); G[v1].push_back(node(v2,len,value)); G[v2].push_back(node(v1,len,value)); } int st ,end; scanf("%d%d",&st,&end); SPFA(st,end); printf("%d %d\n",minDist[end],minValue[end]); } return 0; }