92pts WA#6 7求调 Trajan缩点+入度判定
查看原帖
92pts WA#6 7求调 Trajan缩点+入度判定
1357737
xialingn楼主2024/8/12 22:08

大佬求调!!!救救孩子

思路:缩点后如果新图中只有一个点入度为0则输出该强连通分量的大小,否则输出0

代码如下:

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100005;

typedef pair<int, int> pair_v;
vector<pair_v> adj_all;//用于遍历所有边
vector<int> adj_table[maxn], adj_table_n[maxn];//旧图、新图
bool in_stack[maxn]; 
int scc[maxn], sc, size_sc[maxn]; //连通分量数组;连通分量编号、大小
int s[maxn], st;  
int dfn[maxn], low[maxn], dfncnt;  
int ans; 

void Trajan(int u) {
    low[u] = dfn[u] = dfncnt ++;
    s[++st] = u;
    in_stack[u] = true;
    for (int w : adj_table[u]) {
        if (!dfn[w]) {
            Trajan(w);
            low[u] = min(low[u], low[w]);
        }
        else if(in_stack[w]) {
            low[u] = min(low[u], dfn[w]);
        }
    }
    if (dfn[u] == low[u]) {  
        ++ sc ;
        size_sc[sc] = 0;
        while(s[st] != u) {
            scc[s[st]] = sc;
            in_stack[s[st]] = false;
            size_sc[sc] ++;
            st --;
        }
        scc[u] = sc;
        in_stack[u] = false;
        size_sc[sc] ++;
        st --;
    }
}  //缩点


int main(void) {
    int n, m;
    cin >> n >> m;
    int a, b;
    for (int i=0; i < m; i ++) {
        cin >> a >> b;
        adj_table[b].push_back(a);
        adj_all.push_back({b, a});
    }
    memset(in_stack, false, sizeof(in_stack));
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    dfncnt = st = sc = 0;
    for (int i=1; i <= n; i ++) {
        if (!dfn[i]) Trajan(i);
    }
    int rdu[maxn]; //入度数组
    memset(rdu, 0, sizeof(rdu));
    for (pair_v w : adj_all) {
        if (scc[w.first] != scc[w.second]) {
            ++ rdu[scc[w.second]];
            
        }
    }

    int ans, j=0;
    for (int i=1; i <= sc; i ++) {
        if (rdu[i] == 0) {
            ans = i;
            ++ j;
        }
    }
    if (j==1) cout << size_sc[ans];
    else cout << 0;
    return 0;
}

2024/8/12 22:08
加载中...