无向图 求加几条边可以得到双联通图 poj 3177

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector> 
using namespace std;
const int maxn = 5050;
vector<int> mp[maxn];
bool g[maxn][maxn];
int dfn[maxn],low[maxn],cnt,ans,d[maxn];
void Tarjan(int u,int fa){
	dfn[u] = low[u] = ++cnt;
	for( int i = 0; i < mp[u].size(); i++){
		int v = mp[u][i];
		if(!dfn[v]){
			Tarjan(v,u);
			low[u] = min(low[u],low[v]); 
		}
		else if(v != fa){
			low[u] = min(low[u],dfn[v]);
		}
	}
}
int main(){
	int n,r;
	while(scanf("%d%d",&n,&r) == 2){
		cnt = ans = 0;
		memset(g,0,sizeof(g));
		memset(dfn,0,sizeof(dfn));
		memset(low,0,sizeof(low));
		memset(d,0,sizeof(d));
		while(r--){
			int u,v;
			scanf("%d%d",&u,&v);
			if(!g[u][v]){
				g[u][v] = 1;
				mp[u].push_back(v);
				mp[v].push_back(u);
			}
		}
		Tarjan(1,-1);
		for( int u = 1; u <= n; u++){
			for( int j = 0; j < mp[u].size(); j++){
				int v = mp[u][j];
				if(low[v] != low[u])
				d[low[u]]++;
			}
		}
		for( int i = 1; i <= n; i++){
			if(d[i] == 1) ans++;
		}
		printf("%d\n",(ans+1)/2);
		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sky_zdk/article/details/79630438
今日推荐