时间:2016-04-02 20:30:40 星期六
题目编号:[2016-04-02][POJ][3268][Silver Cow Party]
题目大意:给定一个有向图图,1~n牛到k牛出参加party,所有牛都走最快的路,问所有牛中往返,耗时最长为多少,
分析:
- 求从1 -> k的最短路和 k -> 1的最短路之和,
- 从1跑一次Dijkstra,从k跑一次Dijkstra,求和,
- 在discuss发现有个叫矩阵转置的东西,即k->x的最短路,相当于把所有边反转之后,x -> k的最短路
#include <queue>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;const int maxn = 1000 + 10;struct Node{ int v,c; Node(int _v = 0,int _c = 0):v(_v),c(_c){} bool operator < (const Node & a)const { return c > a.c; }};int vis[maxn],d1[maxn],d2[maxn],a[maxn][maxn],n,m,x;void Dijkstra(int d[],int s){ priority_queue< Node > q; memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(int) * (n + 1)); d[s] = 0; q.push(Node(s,0)); Node tmp; while(!q.empty()){ tmp = q.top();q.pop(); int u = tmp.v; if(vis[u]) continue; vis[u] = 1; for(int i = 1;i <= n ; ++i){ if(!vis[i]&& a[u][i] && d[i] > d[u] + a[u][i]){ d[i] = d[u] + a[u][i]; q.push(Node(i,d[i])); } } }}void trans(){ for(int i = 1;i <= n ;++i) for(int j = i + 1;j <= n ; ++j) swap(a[i][j],a[j][i]); }int main(){ int cntcase = 0,_a,b,c; int t; scanf("%d%d%d",&n,&m,&x); memset(a,0,sizeof(a)); for(int i = 0;i < m ; ++i){ scanf("%d%d%d",&_a,&b,&c); a[_a][b] = c; } Dijkstra(d1,x); trans(); Dijkstra(d2,x); int ans = 0; for(int i = 1;i <= n ; ++i){ ans = max(ans,d2[i]+d1[i]); } printf("%d\n\n",ans); return 0;}