大佬求调!!!救救孩子
思路:缩点后如果新图中只有一个点入度为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;
}