hdu 5631 Rikka with Graph 并查集

众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

给出一张 n 个点 n+1 条边的无向图,你可以选择一些边(至少一条)删除。

现在勇太想知道有多少种方案使得删除之后图依然联通。
/*
Title :
Status:
By wf,
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#define FOR(i,s,t) for(int i = (s) ; i <= (t) ; ++i )

typedef long long ll;
typedef unsigned long long ull;
using namespace std;

const int inf=0x3f3f3f3f;
const int maxn=105;


int t,n;
int u[maxn],v[maxn];
bool flag[maxn];

int fa[105];

int find(int x){
	return fa[x]==x ? x : fa[x]=find(fa[x]);
}
int merge(int x,int y){
	 x=find(x);
	 y=find(y);
	if(x!=y){
		fa[x]=y;
		return 1;
	}
	return 0;
}

bool check(){
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	//memset(fa,0,n+1<<2);
	int res=0;
	for(int i=0;i<=n;++i){
		if(flag[i]==0)
			res+=merge(u[i],v[i]);
	}
	if(res==n-1){

		return 1;
	}
	else return 0;
}

int main()
{
	//freopen("in.txt","r",stdin);
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		int x,y;
		memset(flag,0,sizeof flag);
		for(int i=0;i<=n;++i){
			scanf("%d%d",&u[i],&v[i]);
		}
		int ans=0;
		for(int i=0;i<=n;++i){
			flag[i]=1;
			//cout<<"i=="<<i<<endl;
			ans += check();
			for(int j=i+1;j<=n;++j){
				flag[j]=1;
				//cout<<"i=="<<i<<"j=="<<j<<endl;
				ans += check();
				flag[j]=0;
			}
			flag[i]=0;
		}
		printf("%d
",ans );

	}	
	return 0;
}
原文地址:https://www.cnblogs.com/bruce27/p/5240439.html