60pts求助
查看原帖
60pts求助
759274
Stevehim楼主2023/8/9 14:44

rt,本来以为是求边双的板子,但是发现求完的tot跟答案不一样,tot / 2得了六十分,为什么呢QAQ

//模板来自P8436供题人题解
#include <bits/stdc++.h>
#define maxn 2000010
#define maxm 8000010
using namespace std;
int n,m,cnt = 1;
int tim;
int tot;
int dfn[maxn],low[maxn],head[maxn],belong[maxn]; //链式前向星存图
struct edge{
	int nxt,to;
}a[maxm];
bool ge[maxm]; //割边判断
vector<int> G[maxn];
int outdegree[maxn];
long long ans = 0;
void add(int x,int y){ //链式前向星加边
	a[++cnt].to = y;
	a[cnt].nxt = head[x];
	head[x] = cnt;
}

void tarjan(int x,int fa){ //fa便是来的边
	dfn[x] = low[x] = ++tim;
	for(int i = head[x];i;i = a[i].nxt){
		int u = a[i].to;
		if(!dfn[u]){
			tarjan(u, i);
			low[x] = min(low[x],low[u]); //更新
			if(dfn[x] < low[u]){ //割边的判定方法
				ge[i] = ge[i ^ 1] = true; //双向边所以都标记,i ^ 1是因为他们是相邻建的边
			}
		}else if(i != (fa ^ 1)){
			low[x] = min(low[x],dfn[u]);
		}
	}
}

void dfs(int x){
	belong[x] = tot;
	if(x){
		G[tot].push_back(x);
	}
	for(int i = head[x];i;i = a[i].nxt){
		int u = a[i].to;
		if(belong[u] || ge[i]) continue; //是割边则返回
		dfs(u);
	}
}
int x[maxn],y[maxn];
int main(){
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		cin >> x[i] >> y[i];
//		if(x == y) continue;
		add(x[i],y[i]),add(y[i],x[i]);
	}
	for(int i = 1; i <= n; i++){
		if(!dfn[i]) tarjan(i,0);
	}
	for(int i = 1; i <= n; i++){
		if(!belong[i]) {
			++tot;
			dfs(i);
		}
	}
	cout << tot / 2<< endl;
	return 0;
}
2023/8/9 14:44
加载中...