[SDUT](3363)数据结构实验之图论七:驴友计划 ---单源最短路径(图)
数据结构实验之图论七:驴友计划
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。
Input
连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。
Output
在同一行中输出路径长度和收费总额,数据间用空格间隔。
Example Input
1 4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
Example Output
3 40
注:加权无向图
解题新知:这个题目具有两种权值,一是距离,二是花费。那么我们就可以使用结构体,方便描述图
继续Dijkstra算法~
AC代码:
#include<iostream> #include<cstring> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 550 struct City { int len; int fee; }; struct City mmap[MAX][MAX]; bool vis[MAX]; int dist[MAX]; int cost[MAX]; void dijkstra(int st,int en,int n) { for(int i=0;i<n;i++) { dist[i]=mmap[st][i].len; cost[i]=mmap[st][i].fee; } int mmin=0; int k; vis[st]=true; for(int i=0;i<n;i++) { mmin=INF; for(int j=0;j<n;j++) { if(!vis[j] && dist[j]<mmin) { mmin=dist[j]; k=j; } } vis[k]=true; for(int j=0;j<n;j++) { if(!vis[j] && dist[k]+mmap[k][j].len<dist[j]) { dist[j]=dist[k]+mmap[k][j].len; cost[j]=cost[k]+mmap[k][j].fee; } else if(!vis[j] && dist[k]+mmap[k][j].len==dist[j]) { cost[j]=min(cost[k]+mmap[k][j].fee,cost[j]); } } } } int main() { int t; cin>>t; while(t--) { memset(vis,false,sizeof(vis)); memset(dist,0,sizeof(dist)); memset(cost,0,sizeof(cost)); int n,m,Start,End; int c1,c2,len,fee; cin>>n>>m>>Start>>End; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(i==j) mmap[i][j].len=mmap[i][j].fee=0; else mmap[i][j].len=mmap[i][j].fee=INF; } } while(m--) { cin>>c1>>c2>>len>>fee; if(len<mmap[c1][c2].len && fee<mmap[c1][c2].fee) { mmap[c1][c2].len=mmap[c2][c1].len=len; mmap[c1][c2].fee=mmap[c2][c1].fee=fee; } } dijkstra(Start,End,n); cout<<dist[End]<<" "<<cost[End]<<endl; } return 0; }