您的位置:首页 > 其它

spfa+邻接表

2020-05-11 04:11 225 查看

给你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 <stdio.h>#include <algorithm>#include <string.h>#include <math.h>#include <queue>using namespace std;const int N = 1005;const int M =100005;const int INF =99999999;struct Edge{int v,d,p,next;} edge[2*M];int head[N];int n,m;void addedge(int u,int v,int d,int p,int &k){edge[k].v =v,edge[k].d =d,edge[k].p=p,edge[k].next=head[u],head[u]=k++;}int dis[N],time[N],cost[N];bool vis[N];bool spfa(int s){queue<int >q;memset(vis,false,sizeof(vis));memset(time,0,sizeof(time));for(int i=1; i<=n; i++){dis[i] = (i==s)?0:INF;cost[i] = (i==s)?0:INF;}q.push(s);time[s]++;while(!q.empty()){int u = q.front();q.pop();vis[u]=false;for(int k = head[u]; k!=-1; k=edge[k].next){int v = edge[k].v,d= edge[k].d,p = edge[k].p;if(dis[v]>dis[u]+d||(dis[v]==dis[u]+d)&&(cost[v]>cost[u]+p)){dis[v]=dis[u]+d;cost[v]=cost[u]+p;if(!vis[v]){vis[v] = true;time[v]++;q.push(v);}if(time[v]>n) return false;}}}return true;}int main(){while(scanf("%d%d",&n,&m)!=EOF,n+m){memset(head,-1,sizeof(head));int tot = 0,u,v,d,p;for(int i=0; i<m; i++){scanf("%d%d%d%d",&u,&v,&d,&p);addedge(u,v,d,p,tot);addedge(v,u,d,p,tot);}int s,t;scanf("%d%d",&s,&t);spfa(s);printf("%d %d\n",dis[t],cost[t]);}return 0;}
Starry_Sky_Dream原创文章 50获赞 4访问量 2338关注私信
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: