题目链接:链接传送门
题目大意:有编号为1-N的牛,它们之间存在一些单向的路径。给定一头牛的编号,其他牛要去拜访它并且拜访完之后要返回自己原来的位置,求这些牛中所花的最长的来回时间是多少。
开始跑Floyd,想的是把所有点跑出来,超时了
百度大牛博客,反向建图,这操作,行吧,反向建图一次,跑两次Dijkstra
附上不优秀代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)
const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1005;
int mp1[N][N],mp2[N][N];
int dis1[N],dis2[N];
int n,m,x;
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
{
mp1[i][j]=0;
mp2[i][j]=0;
}
else
{
mp1[i][j]=INF;
mp2[i][j]=INF;
}
}
}
}
void djs1(int st)
{
int vis[n];
for(int i=1;i<=n;i++)
{
dis1[i]=mp1[st][i];
vis[i]=0;
}
vis[st]=1;
for(int i=1;i<n;i++) //更新dis数组,起点不用更新了,所以是n-1次
{
int minn=INF; //更新最小距离点
int next=-1; //确定下一个点
for(int j=1;j<=n;j++)
{
if(vis[j]==0&&dis1[j]<minn)
{
minn=dis1[j];
next=j;
}
}
if(next==-1) //当前已不存在点
continue;
vis[next]=1;
for(int j=1;j<=n;j++)
{
if(vis[j]==0) //vis[j]=1已为最短路径
dis1[j]=min(dis1[j],dis1[next]+mp1[next][j]); //以next为中间点进行松弛
}
}
//return dis[ed]; //找到st到ed的最短路
}
void djs2(int st)
{
int vis[n];
for(int i=1;i<=n;i++)
{
dis2[i]=mp2[st][i];
vis[i]=0;
}
vis[st]=1;
for(int i=1;i<n;i++) //更新dis数组,起点不用更新了,所以是n-1次
{
int minn=INF; //更新最小距离点
int next=-1; //确定下一个点
for(int j=1;j<=n;j++)
{
if(vis[j]==0&&dis2[j]<minn)
{
minn=dis2[j];
next=j;
}
}
if(next==-1) //当前已不存在点
continue;
vis[next]=1;
for(int j=1;j<=n;j++)
{
if(vis[j]==0) //vis[j]=1已为最短路径
dis2[j]=min(dis2[j],dis2[next]+mp2[next][j]); //以next为中间点进行松弛
}
}
//return dis[ed]; //找到st到ed的最短路
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//std::ios::sync_with_stdio(false);
int a,b,t;
while(~scanf("%d%d%d",&n,&m,&x))
{
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&t);
mp1[a][b]=t;
mp2[b][a]=t;
}
djs1(x);
djs2(x);
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,dis1[i]+dis2[i]);
printf("%d\n",ans);
}
return 0;
}