Silver Cow Party
One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1…N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.
Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow’s return route might be different from her original route to the party since roads are one-way.
Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?
翻译:
来自 n 个农场(1≤n≤1000)的1. .n头奶牛将参加农场 x(1≤x≤n)举办的大型奶牛派对。共有m(1≤m≤100000)单向(单向道路连接成对农场);i 号公路需要 Ti(1≤Ti≤100)单位的穿越时间。
每头牛都必须走到派对上,派对结束后,回到自己的农场。每头母牛都懒惰,因此选择了一条时间最短的最佳路线。一头牛的返回路线可能不同于她最初去派对的路线,因为道路是单向的。
在所有的奶牛中,一头奶牛步行去聚会和回来必须花多长时间?
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.
翻译:
第1行:三个空格分隔的整数,分别为:n、m和x
第2…M+1行:第 i+1行用三个空格分隔的整数(ai、bi和ti)描述了道路I。所描述的道路从农场ai到农场bi,需要Ti时间单位进行穿越。
output
Line 1: One integer: the maximum of time any one cow must walk.
第1行:一个整数:任何一头牛必须行走的最长时间。
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.
翻译:
奶牛4直接进入一方(3个单位),通过农场1和3(7个单位)返回,总共10个时间单位。
一个比较基础的dijkstra 算法问题,就是要注意他是要求的是一来一回的总共最大时间,而且路都是单向的。先计算x农场到其他农场用的最短时间,在枚举其他农场到x农场的最短时间,记录下最大来回时间。但是要注意时间复杂度,小心超时,所以我这里用了一个转置矩阵,交换 map[i][j] 与 map[j][i] 的值,这样就能避免超时。
代码如下
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf= 99999999;
int dis1[1111],dis[1111],map[1111][1111],visit[1111];
int m,n,x,a,b,t,i,j,k,minx,temp,v,ans=0;
void dijkstra()
{
memset(visit,0,sizeof(visit)); //初始化visit数组
for(i=1;i<=n;i++)
dis[i]=map[x][i]; //初始化
visit[x]=1;
v=x;
for(k=2;k<=n;k++) //求出距离x 最近的一个 牛场 并记录下来
{
minx=inf;
for(j=1;j<=n;j++)
{
if(!visit[j]&&dis[j]<minx)
{
minx=dis[j];
v=j;
}
}
visit[v]=1;
for(i=1;i<=n;i++) //求出各个 牛场 到x 的最短距离
if(!visit[i]&&dis[i]>dis[v]+map[v][i])
dis[i]=dis[v]+map[v][i];
}
}
int main()
{
scanf("%d%d%d",&n,&m,&x); //输入
for(i=1;i<=n;i++) //将数组map 初始化
for(j=1;j<=n;j++)
{
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
}
for(i=0;i<m;i++) //输入道路信息,并储存在map中
{
scanf("%d%d%d",&a,&b,&t);
if(t<map[a][b])
map[a][b]=t;
}
dijkstra(); //第一次调用,得出x 到 其他牛场的最短时间
for(i=1;i<=n;i++) //储存第一次调用得到的值
dis1[i]=dis[i];
for(i=1;i<=n;i++) //最重要的!!转置矩阵,也就是交换map[i][j]与map[j][i]的值
for(j=i+1;j<=n;j++) //相当于把求其他农场到x 的距离 转换成了求 x 到其他牛场的距离
{
temp=map[i][j];
map[i][j]=map[j][i];
map[j][i]=temp;
}
dijkstra(); //第二次调用 ,再求 x 到其他牛场的距离
for(i=1;i<=n;i++)
if(i!=x)
ans=max(ans,dis1[i]+dis[i]); //求出两次调用结果之和最大
printf("%d\n",ans); //输出
return 0;
}