码风有亿点点抽象
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
long long read(){
char ch=getchar();
long long res=0;
short f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f*=-1;
for(;ch>='0'&&ch<='9';ch=getchar())res=(res<<3)+(res<<1)+(ch^48);
return res*f;
}
class Solution{
public:
void solve(){
for(int i = 1; i <= n; i++) if(order[i] == 0) Tarjan(i, 0);
int cnt = 0, index = 0, ans = 0;
for(int i = 1; i <= n; i++) if(top[i] != index && degree[top[i]] == 0) index = top[i], cnt++;
if(cnt == 1) for(int i = 1; i <= n; i++) if(top[i] == index) ans++;
printf("%d\n", ans);
return ;
}
void print(){
printf("order :\n");
for(int i = 1; i <= n; i++)
printf("%d ", order[i]);
putchar('\n');
printf("top :\n");
for(int i = 1; i <= n; i++)
printf("%d ", top[i]);
putchar('\n');
printf("degree :\n");
for(int i = 1; i <= n; i++)
printf("%d ", degree[i]);
putchar('\n');
return ;
}
Solution() : n(0), m(0){}
Solution(int __n, int __m) : n(__n), m(__m), path(__n + 1), order(__n + 1), top(__n + 1), degree(__n + 1){
for(int i = 0; i < m; i++){
int u = read(), v = read();
path[u].emplace_back(v);
path[v].emplace_back(u);
}
}
protected:
int n, m;
int count = 0;
std::vector<std::pair<int, int>>ans;
std::vector<std::vector<int>>path;
std::vector<int>order, top, degree;
void Tarjan(int u, int pre){
top[u] = order[u] = ++count;
for(int i = 0; i < path[u].size(); i++){
int v = path[u][i];
if(order[v] != 0 && v != pre) top[u] = std::min(top[u], order[v]);
if(order[v] == 0){
Tarjan(v, u);
if(order[u] < top[v]) degree[order[u]]++;
top[u] = std::min(top[u], top[v]);
}
}
return ;
}
};
int main(){
int n = read(), m = read();
Solution ans(n, m);
ans.solve();
//ans.print();
return 0;
}
记录详情 ,可以看到很多是因为输出0而WA
但更抽象的是,我最开始没看题建的是双向边,然后是40pts,但注意到这个问题后改成建单边后反倒变成28pts了