题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4263
思路:将红边和蓝边单独求一次生成树,求的红边最多可以加入的边数cntr,蓝边最多可以加入的边数cntb,只要k满足条件k>=(n-1-cntr)&&k<=cntb,就说明可以生成这样的spanning tree.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 1100 7 int parent[MAXN]; 8 int n,m,k; 9 struct Edge{ 10 int u,v; 11 }B[MAXN*MAXN],R[MAXN*MAXN]; 12 13 int Find(int x) 14 { 15 if(x==parent[x]) 16 return parent[x]; 17 parent[x]=Find(parent[x]); 18 return parent[x]; 19 } 20 21 bool Union(int u,int v) 22 { 23 int r1=Find(u),r2=Find(v); 24 if(r1==r2)return false; 25 parent[r1]=r2; 26 return true; 27 } 28 29 30 int main() 31 { 32 // freopen("1.txt","r",stdin); 33 int ansb,ansr,cntb,cntr; 34 char str[4]; 35 while(scanf("%d%d%d",&n,&m,&k),(n+m+k)) 36 { 37 ansb=ansr=cntb=cntr=0; 38 for(int i=1;i<=m;i++){ 39 scanf("%s",str); 40 if(str[0]=='B'){ 41 scanf("%d%d",&B[cntb].u,&B[cntb].v); 42 cntb++; 43 }else { 44 scanf("%d%d",&R[cntr].u,&R[cntr].v); 45 cntr++; 46 } 47 } 48 for(int i=1;i<=n;i++)parent[i]=i; 49 for(int i=0;i<cntb;i++){ 50 int u=B[i].u,v=B[i].v; 51 if(Union(u,v))ansb++; 52 } 53 for(int i=1;i<=n;i++)parent[i]=i; 54 for(int i=0;i<cntr;i++){ 55 int u=R[i].u,v=R[i].v; 56 if(Union(u,v))ansr++; 57 } 58 if(k>=(n-1-ansr)&&k<=ansb){ 59 puts("1"); 60 }else 61 puts("0"); 62 } 63 return 0; 64 }