时间: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;
}