[kuangbin带你飞] Silver Cow Party(来回单向最短路)

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);
}

猜你喜欢

转载自blog.csdn.net/qq_41428565/article/details/80193321