好久没有写图论,我成了一个废物

https://codeforc.es/contest/1454/problem/E

看样例就能看懂题意,就是找基环树的环,然而我环找错了。。。。。。

我是sb,我要学图!!!

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int maxn = 3e5+111;

vector<int>G[maxn];
void add(int be,int en){
	G[be].push_back(en);
}
int vis[maxn];
stack<int>s;

vector<int>ins;

int dfs(int x,int fa){
	if(vis[x]) {
		
		if(ins.size() != 0) return 0;
		
		while(s.size()){
			ins.push_back(s.top());
			if(s.top() == x) break;
			s.pop();
		}
		return 0;
	}
	vis[x] = 1;
	s.push(x);
	
	for(int i=0;i<G[x].size();i++){
		int p = G[x][i];
		if(p == fa) continue;
		dfs(p,x);
	}
	
	if(s.size()) s.pop();
	
	return 0;
}
int cnt =0 ;
int dfs(int x){
	if(vis[x]) return 0;
	vis[x] = 1;
	cnt++;
	for(int i=0;i<G[x].size();i++){
		dfs(G[x][i]);
	}
	return 0;
}
int f[maxn];


int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		
		while(s.size()) s.pop();
		
		for(int i=1;i<=n+11;i++){
			G[i].clear();
			vis[i] = 0;
		}
		
		ins.clear();
		
		for(int i=0;i<n;i++){
			int be,en;
			scanf("%d%d",&be,&en);
			add(be,en);
			add(en,be);
		}
		dfs(1,-1);
		
		for(int i=1;i<=n;i++){
			vis[i] = 0;
			f[i] = 0;
		}
		
		for(int i=0;i<ins.size();i++){
			f[ins[i]] = 1;
			vis[ins[i]] = 1;
		}
		ll len = ins.size();
		ins.clear();
		
		
		for(int i=1;i<=n;i++){
			if(f[i]){
				vis[i] = 0;
				cnt = 0;
				dfs(i);
				if(cnt != 1){
					ins.push_back(cnt-1);
				}
				
			}
		}
		
		ll ans = 1LL*n*(n-1)/2;
		ans += 1LL*len*(len-1)/2;
		
		for(int i=0;i<ins.size();i++){
			ans += 1LL*(ins[i]) *(n - ins[i]-1);
			n -= ins[i];
//			cout<<ins[i]<<endl;
		}
		printf("%lld
",ans);
	}
	return 0;
}

/*

20000
11
9 1
1 2
7 1
4 10
8 5
4 6
4 2
7 5
2 5
3 1
11 6


*/

  

原文地址:https://www.cnblogs.com/lesning/p/14039130.html