Silver Cow Party POJ - 3268
给出n,m,代表牛数和边数,接着是m条有向边,代表从牛a到牛b需要花费c时间,现在所有牛要到牛x那里去参加聚会,并且所有牛参加聚会后还要回来,给你牛x,除了牛x之外的牛,他们都有一个参加聚会并且回来的最短时间,从这些最短时间里找出一个最大值输出 N<=1000,M<=100,000
Input
Line 1: Three space-separated integers, respectively: N, M, and X
Lines 2… M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Output
Line 1: One integer: the maximum of time any one cow must walk.
Sample Input
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
Sample Output
10
Hint
Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.
题意:牛儿们到牛X家里聚会,聚会后还要回来。求牛儿们到牛X家聚会再回来所用的最短时间,输出最短时间中的最大值。
思路:单向边,先用迪杰斯特拉算法求出牛X到其他牛家的最短路径,为牛儿们去牛X家的最短距离。然后将矩阵转置,再重复上一个步骤,为牛儿们从牛X家到自己家的最短路径。然后相加,求最大值。
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1010;
const int inf=10000000;
int a[maxn][maxn];
bool vis[maxn];
int d[maxn],way[maxn];//分别存去时和回来时的最短路径
int m,n;
void dij(int s)
{
memset(vis,0,sizeof(vis));
fill(d,d+maxn,inf);
d[s]=0;
int i,j;
for(i=0;i<n;i++)
{
int min=inf,u=-1;
for(j=0;j<n;j++)
{
if(vis[j]==false&&d[j]<min)
{
u=j;
min=d[j];
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;v<n;v++)
{
if(vis[v]==false&&a[u][v]!=inf&&d[u]+a[u][v]<d[v])
{
d[v]=d[u]+a[u][v];
}
}
}
}
int main()
{
fill(a[0],a[0]+maxn*maxn,inf);
int i,j,s;
cin>>n>>m>>s;
for(i=0;i<n;i++)
{
a[i][i]=0;
}
for(i=0;i<m;i++)
{
int x,y,k;
cin>>x>>y>>k;
x--;
y--;
a[x][y]=k;
}
s--;
dij(s);
for(i=0;i<n;i++)
{
way[i]=d[i];
}
for(i=0;i<n;i++)//矩阵转置
{
for(j=i;j<n;j++)
{
swap(a[i][j],a[j][i]);
}
}
dij(s);
int max=0;
for(i=0;i<n;i++)//求最大值
{
if(d[i]+way[i]>max)
{
max=d[i]+way[i];
}
}
cout<<max;
return 0;
}