N个农场(1≤N≤1000)各有一头奶牛,方便地编号为1.N,准备参加在农场#X(1≤X≤N)举行的大型奶牛聚会。
总共有M(1≤M≤100,000)个单向(单向道路)连接成对的农场;道路I需要Ti(1≤Ti≤100)个单位的时间来遍历。
每头牛都必须步行去参加聚会,当聚会结束后,回到自己的农场。
每头牛都很懒,因此选择了一条时间最短的最优路线。
由于道路是单向的,因此奶牛的返回路线可能不同于她去聚会的原始路线。
在所有的奶牛中,一头奶牛必须步行去聚会和回来的最长时间是多少?
输入。
第1行:三个空格分隔的整数,分别为:N、M和X。
第2行.。
M+1:行I+1用三个空格分隔的整数描述道路I:AI、Bi和Ti。
描述的道路从农场AI到农场Bi,需要Ti时间单位来穿越。
输出量。
第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
关键在于思维,直接做的话,迪杰斯特拉算法或者佛洛依德算法都一定超时,优化过的迪杰斯特拉算法也有可能超时。
首先,x到其他所有的点距离好求,而其他点到x的距离,如果把原图逆过来 map[i][j]=map[j][i],再求x到其他所有的点距离,即为其他点到x的距离。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <string>
using namespace std;
int mapp[1010][1010],mapp0[1010][1010];
int temp[1010],temp0[1010],flg[1010];
int main()
{
int i,j,k,x,l,n,m,maxx,mark;
scanf("%d%d%d",&n,&m,&x);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i!=j)
{
mapp[i][j]=1061109567;
mapp0[i][j]=1061109567;
}
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&j,&k,&l);
if(mapp[j][k]>l)
mapp[j][k]=l;
if(mapp0[k][j]>l)
mapp0[k][j]=l;
}
for(j=1;j<=n;j++)
temp[j]=mapp[x][j];
flg[x]=1;
for(j=1;j<n;j++)
{
maxx=1061109567;
mark=x;
for(i=1;i<=n;i++)
{
if(flg[i]==0&&temp[i]<maxx)
{
maxx=temp[i];
mark=i;
}
}
flg[mark]=1;
for(i=1;i<=n;i++)
{
if(temp[i]>temp[mark]+mapp[mark][i])
temp[i]=temp[mark]+mapp[mark][i];
}
}
for(i=1;i<=n;i++)
flg[i]=0;
for(j=1;j<=n;j++)
temp0[j]=mapp0[x][j];
flg[x]=1;
for(j=1;j<n;j++)
{
maxx=1061109567;
mark=x;
for(i=1;i<=n;i++)
{
if(flg[i]==0&&temp0[i]<maxx)
{
maxx=temp0[i];
mark=i;
}
}
flg[mark]=1;
for(i=1;i<=n;i++)
{
if(temp0[i]>temp0[mark]+mapp0[mark][i])
temp0[i]=temp0[mark]+mapp0[mark][i];
}
}
maxx=0;
for(i=1;i<=n;i++)
{
if(maxx<temp0[i]+temp[i])
maxx=temp0[i]+temp[i];
}
printf("%d",maxx);
return 0;
}