HDU 3790 最短路径问题
最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 33061 Accepted Submission(s):
9713
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
Source
Recommend
notonlysuccess | We have carefully selected several
similar problems for you: 1874 2066 1217 2112 1142
思路:跑一边spfa即可,在spfa时多记录一个量。
错因:两个点之间可能有多条边,要取边权最小的。
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100010 #define INF 0x3f3f3f3f using namespace std; queue<int>que; int n,m,s,t,tot; int a[1005][1005],b[1005][1005]; int dis[1005],pay[1005],vis[1005]; int to[MAXN*2],net[MAXN*2],cap[MAXN*2],sum[MAXN*2],head[1005]; void add(int u,int v,int w,int ww){ to[++tot]=v;cap[tot]=w;sum[tot]=ww;net[tot]=head[u];head[u]=tot; to[++tot]=u;cap[tot]=w;sum[tot]=ww;net[tot]=head[v];head[v]=tot; } void spfa(){ while(!que.empty()) que.pop(); memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); memset(pay,0x3f,sizeof(pay)); que.push(s);vis[s]=1; dis[s]=0;pay[s]=0; while(!que.empty()){ int now=que.front(); que.pop();vis[now]=0; for(int i=head[now];i;i=net[i]) if(dis[to[i]]>dis[now]+cap[i]){ dis[to[i]]=dis[now]+cap[i]; pay[to[i]]=pay[now]+sum[i]; if(!vis[to[i]]){ vis[to[i]]=1; que.push(to[i]); } } else if(dis[to[i]]==dis[now]+cap[i]&&pay[now]+sum[i]<pay[to[i]]){ pay[to[i]]=pay[now]+sum[i]; if(!vis[to[i]]){ vis[to[i]]=1; que.push(to[i]); } } } } int main(){ while(scanf("%d%d",&n,&m)&&n!=0&&m!=0){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j) a[i][j]=b[i][j]=0; else a[i][j]=b[i][j]=INF; for(int i=1;i<=m;i++){ int x,y,z,zz; scanf("%d%d%d%d",&x,&y,&z,&zz); if(a[x][y]>z){ a[x][y]=a[y][x]=z; b[x][y]=b[y][x]=zz; } } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(a[i][j]!=INF) add(i,j,a[i][j],b[i][j]); scanf("%d%d",&s,&t); spfa(); printf("%d %d\n",dis[t],pay[t]); tot=0;memset(head,0,sizeof(head)); } return 0; }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。