POJ-3268 牛的來回最長時間(單源最短路徑)
阿新 • • 發佈:2018-12-12
題目大意:
有編號為1-N的牛,它們之間存在一些單向的路徑。給定一頭牛的編號,其他牛要去拜訪它並且拜訪完之後要返回自己原來的位置,求這些牛中所花的最長的來回時間是多少。
給出N頭牛,M條路,要拜訪牛的編號X。
思路:
也就是每頭牛都要已最短路徑到達X號牛,並且從X號牛再回到自己原處。可以反推,從X號牛開始到每頭牛的最短距離,並且再回到X號牛的最短距離。但是你通過原圖只能知道每頭牛到X號牛回去的路,而不知去的最短路徑。可以再用一個數組來儲存把每條路徑倒過來後的距離,這樣就可以求得去的最短路徑。最短路徑就是用Dijkstra演算法套模板就可以。
程式碼:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1010; const int INF = 9000000; bool vis[MAXN]; bool vis1[MAXN]; int map[MAXN][MAXN]; int map1[MAXN][MAXN]; int dis[MAXN]; int dis1[MAXN]; void Dij(int start,int n) { for(int i = 1; i <= n; i++) { dis[i] = map[start][i]; dis1[i] = map1[start][i]; vis[i] = false; vis1[i] = false; } dis[start] = 0; dis1[start] = 0; for(int j = 1; j < n; j++) { int k = -1; int k1 = -1; int Min = INF; int Min1 = INF; for(int i = 1; i <= n; i++) { if(!vis[i] && dis[i] < Min) { Min = dis[i]; k = i; } if(!vis1[i] && dis1[i] < Min1) { Min1 = dis1[i]; k1 = i; } } if(k != -1) { vis[k] = true; for(int i = 1; i <= n; i++) { if(!vis[i] && dis[k] + map[k][i] < dis[i]) { dis[i] = dis[k] + map[k][i]; } } } if(k1 != -1) { vis1[k1] = true; for(int i = 1; i <= n; i++) { if(!vis1[i] && dis1[k1] + map1[k1][i] < dis1[i]) { dis1[i] = dis1[k1] + map1[k1][i]; } } } } } int main() { int n, m, x; cin >> n >> m >> x; memset( map, INF, sizeof(map)); memset( map1, INF, sizeof(map1)); for(int i = 1; i <= m; i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); map[a][b] = c; map1[b][a] = c; } for(int i = 1; i <= n; i++) { map[i][i] = 0; map1[i][i] = 0; } Dij(x,n); int sum; int maxx = -1; for(int i = 1; i <= n; i++) { if(i != x) { sum = dis[i] + dis1[i]; if(sum > maxx) maxx = sum; } } cout << maxx << endl; return 0; }