hdoj 3790 最短路徑問題(Dijkstra)
阿新 • • 發佈:2018-11-07
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=3790
最短路徑問題 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) 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時輸入結束。
Output 輸出 一行有兩個數, 最短距離及其花費。
Sample Input 3 2 1 2 5 6 2 3 4 5 1 3 0 0
Sample Output 9 11
Source |
題目大意:給出起點和終點,輸出起點到終點的 最短距離以及最小花費 解題思路:求兩個點之間的最短距離可以用Dijkstra演算法 然後在邊的權值上加一個花費的變數 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxn 0x3f3f3f int n,m; struct Node{ int path,cost; }map[1010][1010],D[1010]; int visit[1010]; int mini(int x,int y){ return x<y?x:y; } int Dijkstra(int v){//從頂點v開始遍歷,尋找v到各個城市的最小值 //visit[v]=1; memset(D,maxn,sizeof(D)); for(int i=1;i<=n;i++){ D[i].path=map[v][i].path;//初始化從v到各頂點的距離為初始距離 D[i].cost=map[v][i].cost; visit[i]=0;//0表示該點還沒有找到最短路徑 } visit[v]=1;//v點已經加入到集合S中(已經找到最短路徑) for(int i=2;i<=n;i++){//1已經加入到S中,只剩下M-1個點需要加入到S中 Node min; min.cost=maxn; min.path=maxn; int minn=0; for(int j=1;j<=n;j++){//尋找最小值加入集合S中 if(D[j].path==min.path&&D[j].cost<min.cost&&visit[j]==0){//保證每次加入的都是最短路徑且是最小花費 min.cost=D[j].cost; minn=j; } else if(D[j].path<min.path&&visit[j]==0){ min.path=D[j].path; min.cost=D[j].cost; minn=j; } } visit[minn]=1;//表示該點已經加入到S中 for(int k=1;k<=n;k++){//加入到集合S中一個點之後一定可以更新一些剩餘的點,使他們到v的距離變小 if(D[k].path==map[minn][k].path+min.path&&D[minn].cost+map[minn][k].cost<D[k].cost){ D[k].cost=D[minn].cost+map[minn][k].cost; } else if(D[k].path>map[minn][k].path+min.path){ D[k].path=map[minn][k].path+min.path; D[k].cost=D[minn].cost+map[minn][k].cost; } } } } //求的是一點(形式引數表示的點)到其他各點的距離 int main(){ int a,b,d,p,s,e; while(scanf("%d %d",&n,&m)!=EOF&&m&&n){ memset(visit,0,sizeof(visit)); memset(map,maxn,sizeof(map)); for(int i=1;i<=n;i++){ map[i][i].path=0; map[i][i].cost=0; } for(int i=0;i<m;i++){ scanf("%d %d %d %d",&a,&b,&d,&p); if(map[a][b].path>d||(map[a][b].path==d&&map[a][b].cost>p)){//判斷重邊並去重 map[a][b].path=d; map[b][a].path=d; map[a][b].cost=p; map[b][a].cost=p; } } scanf("%d %d",&s,&e); Dijkstra(s); printf("%d %d\n",D[e].path,D[e].cost); } return 0; } //WA原因:沒有考慮重邊