216. 最小花费最短路

【题目描述】:

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

【输入描述】:

多组数据:每组数据描述如下:

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。

n和m为0时输入结束。

【输出描述】:

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

【样例输入】: 3 2

1 2 5 6

2 3 4 5

1 3

0 0

【样例输出】:

9 11

【时间限制、数据范围及描述】:

时间:1s 空间:128M

对于 30%的数据:1<n<=100

对于100%的数据:1<n<=1000; 0<m<100000; s != t; 1<=d,p<=1000

数据组数<=5,注意卡常;

代码

#include<algorithm>
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<queue> using namespace std; int n,m,s,t,Cnt,Next[5000001],head[5000001],to[5000001]; bool visit[5000001]; int dis[5000001],Cost[5000001],val[5000001],cost[5000001]; struct cmp{ bool operator()(int a,int b){ return dis[a]>dis[b]; } }; void Push(int x,int y,int z,int c){ ++Cnt; Next[Cnt]=head[x]; head[x]=Cnt; to[Cnt]=y; val[Cnt]=z; cost[Cnt]=c; } void dijkstra(){ priority_queue<int,vector<int>,cmp> Q; for(int i=1;i<=n;i++){ visit[i]=false; dis[i]=1000000001; Cost[i]=1000000001; } Q.push(s); visit[s]=true; dis[s]=0; Cost[s]=0; while(!Q.empty()){ int u=Q.top(); Q.pop(); visit[u]=false; for(int i=head[u];i;i=Next[i]){ int v=to[i]; if(dis[v]>dis[u]+val[i]||(Cost[v]>Cost[u]+cost[i]&&dis[v]==dis[u]+val[i])){ Cost[v]=Cost[u]+cost[i]; dis[v]=dis[u]+val[i]; if(!visit[v]){ visit[v]=true; Q.push(v); } } } } return; } int main(){ int u,v,w,c; while(scanf("%d%d",&n,&m)){ memset(head,0,sizeof(head)); if(n==0||m==0){ break; } for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&u,&v,&w,&c); Push(u,v,w,c); Push(v,u,w,c); } scanf("%d%d",&s,&t); dijkstra(); printf("%d %d\n",dis[t],Cost[t]); } return 0; } 

此题很烦。

花了好长时间。

猜你喜欢

转载自www.cnblogs.com/xiongchongwen/p/11137597.html