题解 UVA11721 Instant View of Big Bang(SPFA建反图判负环)

题意

给出一张n (\(n\leq1000\)) 点m (\(m\leq2000\)) 边的有向图,要求判断负环,并升序输出可以到负环的点
(多组数据 \(T\leq125\));

算法

建反图 + SPFA判负环 + dfs染色

思路

当建完反图后,负环是不变的,原图上所有能到负环的点在反图上变成了负环能到的点,因此只需找出负环上的点,dfs染色即可

代码

#include <bits/stdc++.h>

using namespace std;

const int maxn = 2e4 + 10;
int n,m,head[maxn],num,flag,dis[maxn],vis[maxn],mark[maxn],cnt[maxn];
struct Edge{
    int then,to,val;
}e[maxn];

void add(int u, int v, int val){e[++num] = (Edge){head[u], v, val}; head[u] = num;}

void dfs(int p){
    mark[p] = 1;
    for(int i = head[p]; i; i = e[i].then){
        int v = e[i].to;
        if(!mark[v]) dfs(v);
    }
}

void SPFA(int st){
    queue<int> q;
    memset(dis,0x3f3f3f3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    dis[st] = 0; vis[st] = 1; q.push(st);
    while(!q.empty()){
        int u = q.front();
        q.pop(); vis[u] = 0;
        for(int i = head[u]; i; i = e[i].then){
            int v = e[i].to;
            if(mark[v]) continue;
            if(dis[v] > dis[u] + e[i].val){
                dis[v] = dis[u] + e[i].val;
                if(!vis[v]){
                    cnt[v] ++;
                    if(cnt[v] > n) flag = 1, dfs(v);  
                    //注意:这里是 >n 而不是 >=n 例如:只有一个点时
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
}

int main(){
    int T;
    scanf("%d", &T);
    for(int t = 1; t <= T; ++ t){
        num = 0; flag = 0;
        memset(head,0,sizeof(head));
        memset(mark,0,sizeof(mark));
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; ++ i){
            int u,v,val;
            scanf("%d%d%d", &u, &v, &val);
            add(v, u, val);
        }
        for(int i = 0; i < n; ++ i) add(n, i, 0);
        SPFA(n);
        printf("Case %d:", t);
        if(!flag) printf(" impossible\n");  //注意空格,换行
        else{
            for(int i = 0; i < n; ++ i)
                if(mark[i]) printf(" %d", i);
            printf("\n");
        }
    }
    return 0;
}
posted @ 2020-10-10 08:18  When_C  阅读(79)  评论(0编辑  收藏  举报