Silver Cow Party
题目链接:D - Silver Cow Party POJ - 3268
题意
给出n个点,一个点x,求其他点到这个点再返回原来位置的最短路径。 并且,给出的边是单向边。
思路
这个题其实只要变换一下思路就会变得十分简单,其余的所有奶牛从自己编号的位置到s去,在回家。选出来回走的路最多的奶牛。因为这是一个有向图,所以到s去不就相当于把所有的路径都反向储存然后从s到其余的各个奶牛。但是好像直接暴力DJs也能过。。。。。。
这样处理会使时间复杂度大大减低,从而得出答案。
代码
/*
Time : 63
Mem : 4.7
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <queue>
#include <ctime>
#include <cmath>
#include <set>
#include <map>
using namespace std;
#define rep(i,j,k) for(int i = (int)(j);i <= (int)(k);i ++)
#define per(i,j,k) for(int i = (int)(j);i >= (int)(k);i --)
#define mmm(a,b) memset(a,b,sizeof(a))
#define sz(x) ((int)(x).size())
#define pb push_back
typedef double db;
typedef long long ll;
const int INF = (int)0x3f3f3f3f;
const int MAXN = (int)1e3+7;
int N,M,X;
int S,E;
int G[MAXN][MAXN];
int dis1[MAXN];
int dis2[MAXN];
queue<int> qu;
void init(){
mmm(G,0x3f);
mmm(dis1,0x3f);
mmm(dis2,0x3f);
}
int main()
{
scanf("%d %d %d",&N,&M,&X);
init();
int x,y,w;
rep(i,1,M){
scanf("%d %d %d",&x,&y,&w);
if (w < G[x][y]) G[x][y] = w;
}
S = X;
dis1[S] = 0;
qu.push(S);
int k;
while (!qu.empty()){
k = qu.front();
qu.pop();
rep(i,1,N){
if (dis1[i] > dis1[k] + G[k][i]){
dis1[i] = dis1[k] + G[k][i];
qu.push(i);
}
}
}
rep(i,1,N){
rep(j,i+1,N){
swap(G[i][j],G[j][i]);
}
}
qu.push(S);
dis2[S] = 0;
while (!qu.empty()) {
k = qu.front();
qu.pop();
rep(i,1,N){
if (dis2[i] > dis2[k] + G[k][i]){
dis2[i] = dis2[k] + G[k][i];
qu.push(i);
}
}
}
int mx = 0;
rep(i,1,N)mx = max(mx,dis1[i]+dis2[i]);
printf("%d\n",mx);
}