POJ3268【最短路】
题意:
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; }