J - 【黄色】这题真的是模板题 Gym - 102072J 【 SPFA 】

版权声明:转载请注明出处,谢谢。 https://blog.csdn.net/Mercury_Lc/article/details/87895349

J - 【黄色】这题真的是模板题

 Gym - 102072J 

在看完其他出题人出的毒瘤题之后,良心出题人终于看不下去了,决定出一道模板题来送给大家一个AC,那么,你们能不能接住这个送来的AC呢?

给出一个nn个结点mm条边的带权有向图,若图中存在负权回路直接输出"-1",否则输出点ss到每个点的最短路的长度,如果ss点不连通,输出"NoPath"。

Input

第一行输入三个值n,m,s(2≤n≤1000,m≤105,1≤s≤N)n,m,s(2≤n≤1000,m≤105,1≤s≤N)

接下来m行,每行三个整数u,v,wu,v,w表示uu和vv之间有一条权值为ww的有向边(1<=u,v,s=N,−106<=w<=106)(1<=u,v,s=N,−106<=w<=106)。

Output

如果存在负权环,输出"-1"

否则输出nn行,分别表示ss点到ii点的最短路,如果s=is=i输出0。 

&&:裸的SPFA,只不过在这里题意说明的是只要存在负权回路就要输出 -1 , 这样就要判断一下如果不是和 s 点连通,就还要判断不连通的那段里面是否存在负权。
// Mercury_Lc
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll maxn = 2e5 + 10;
const ll inf = 0x3f3f3f3f;
struct Edge
{
    ll v;
    ll cost;
    Edge(ll _v = 0, ll _cost = 0) : v(_v),cost(_cost) {}
};
vector<Edge>E[maxn];
void addedge(ll u, ll v, ll w)
{
    E[u].push_back(Edge(v,w));
}
bool vis[maxn];
ll cnt[maxn];
ll dist[maxn];
bool spfa(ll start, ll n)
{
    memset(vis,false,sizeof(vis));
    for(ll i = 1; i <= n; i ++) dist[i] = inf;
    vis[start] = true;
    dist[start] = 0;
    queue<ll>que;
    while(!que.empty()) que.pop();
    que.push(start);
    memset(cnt,0,sizeof(cnt));
    cnt[start] = 1;
    while(!que.empty())
    {
        ll u = que.front();
        que.pop();
        vis[u] = false;
        for(ll i = 0; i < E[u].size(); i ++)
        {
            ll v = E[u][i].v;
            if(dist[v] > dist[u] + E[u][i].cost)
            {
                dist[v] = dist[u] + E[u][i].cost;
                if(!vis[v])
                {
                    vis[v] = true;
                    que.push(v);
                    if(++cnt[v] > n) return false;
                }
            }
        }
    }
    return true;
}
bool vs[maxn];
int main()
{
    ll n,m,s;
    while(~scanf("%lld %lld %lld", &n,&m, &s))
    {
        for(ll i = 0; i < m; i ++)
        {
            ll u,v,w;
            scanf("%lld %lld %lld", &u, &v, &w);
            addedge(u,v,w);
        }
        bool flag = spfa(s,n);
        if(!flag) printf("-1\n");
        else
        {
            int idx = 0;
            int last = 0;
            int y = 0;
            memset(vs,false,sizeof(vs));
            while(1)
            {
                for(int i = 1; i <= n; i ++)
                {
                    if(!vs[i])
                    {
                        if(dist[i]==inf)
                        {
                            idx = i;
                            vs[i] = true;
                            last = 1;
                            break;
                        }
                        else vs[i] = true;
                    }
                }
                bool xx = spfa(idx,n);
                if(!xx)
                {
                    printf("-1\n");
                    y = 1;
                    break;
                }
                if(last == 0) break;
                last = 0;
            }
            if(y == 0)
            {
                bool flag = spfa(s,n);
                for(ll i = 1; i <= n; i ++)
                {
                    if(s == i) printf("0\n");
                    else if(dist[i] == inf) printf("NoPath\n");
                    else printf("%lld\n",dist[i]);
                }
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mercury_Lc/article/details/87895349