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\n",ans ); } return 0; }