最短路徑題,套用Dijkstra演算法,但增加一個頂點A連通所有起點,一個頂點B連通所有終點..問題就轉化為A到B的最短路徑D,D再減去A跟B多出來的距離就得到結果..
CODE:
#include <iostream>using namespace std;const int INF=99999999;const int MAX=1010;int max(int a,int b){ return a>b?a:b;}int T,S,D,L;int map[MAX][MAX];int Dijkstra(int start,int end){ bool hash[MAX]; int path[MAX];//記錄從起始點到i點的最短路徑 for(int i=0;i<=L;i++) { hash[i]=true;//表示該點沒有處理過 path[i]=INF;//表示i點沒被處理過,此時最短路為無窮大 } hash[start]=false; path[start]=0;//注意點 while(start!=end) { for(i=0;i<=L;i++) { if(map[start][i]!=0) { if(path[i]>path[start]+map[start][i]) path[i]=path[start]+map[start][i]; } } int min=INF; for(i=0;i<=L;i++) { if(path[i]<min&&hash[i])//找新的起始點 { min=path[i]; start=i; } } hash[start]=false; }return path[end];}int main (){ int i,a,b,time,s,d; while(scanf("%d%d%d",&T,&S,&D)!=EOF) { memset(map,0,sizeof(map));//初始化 L=0; for(i=1;i<=T;i++) { scanf("%d%d%d",&a,&b,&time); if(!map[a][b]) map[a][b]=map[b][a]=time; else { if(map[a][b]>time) map[a][b]=map[b][a]=time; } if(L<max(a,b)) L=max(a,b);//更新最大編號的點 } for(i=1;i<=S;i++) { scanf("%d",&s); map[0][s]=map[s][0]=1;//添加總的起始點 } L++;//添加結束點 for(i=1;i<=D;i++) { scanf("%d",&d); map[L][d]=map[d][L]=1; } printf("%d/n",Dijkstra(0,L)-2); }return 0;}