POJ3268【最短路】

时间:2022-11-01 03:48:55

题意:

n个点m条有向边,每个点有一头牛,每头牛会沿着各自的最短路先到x点,然后又从x点到各自的点,求这些牛中间最短路程最大的牛。

思路:

从x点到各点的最短路不用说了,裸的最短路;

但是从所有点到x的最短路,那不就是路线反一下,然后求x到所有点的最短路么?

//#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long LL;
const int N=1e3+10;
const int INF=0x3f3f3ff;
int n,m,s;
int dis[N],temp[N];
bool vis[N];
int first[N][N];
int sec[N][N]; void dijkstra1()
{
int i,j;
memset(vis,0,sizeof(vis));
int k;
for(i=1;i<=n;i++)
dis[i]=first[s][i];
vis[s]=1;
dis[s]=0;
for(i=1;i<=n-1;i++)
{
int mimi=INF;
k=0;
for(j=1;j<=n;j++)
{
if(mimi>dis[j]&&!vis[j])
{
mimi=dis[j];
k=j;
}
}
vis[k]=1;
for(j=1;j<=n;j++)
{
if(dis[j]>(dis[k]+first[k][j])&&!vis[j]&&first[k][j]!=INF)
{
dis[j]=dis[k]+first[k][j];
}
}
}
for(int i=1;i<=n;i++)
temp[i]+=dis[i];
} void dijkstra2()
{
int i,j;
memset(vis,0,sizeof(vis));
int k;
for(i=1;i<=n;i++)
dis[i]=sec[s][i];
vis[s]=1;
dis[s]=0;
for(i=1;i<=n-1;i++)
{
int mimi=INF;
k=0;
for(j=1;j<=n;j++)
{
if(mimi>dis[j]&&!vis[j])
{
mimi=dis[j];
k=j;
}
}
vis[k]=1;
for(j=1;j<=n;j++)
{
if(dis[j]>(dis[k]+sec[k][j])&&!vis[j]&&sec[k][j]!=INF)
{
dis[j]=dis[k]+sec[k][j];
}
}
}
for(int i=1;i<=n;i++)
temp[i]+=dis[i];
} int main()
{
while(~scanf("%d%d%d",&n,&m,&s))
{
int u,v,w;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j)
sec[i][j]=first[i][j]=0;
else
sec[i][j]=first[i][j]=INF;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
first[u][v]=w;
sec[v][u]=w;
}
memset(temp,0,sizeof(temp));
dijkstra1();
dijkstra2();
int tyt=temp[1];
for(int i=2;i<=n;i++)
tyt=max(tyt,temp[i]);
printf("%d\n",tyt);
}
return 0;
}