hdu 4263(有限制的生成树)

题目链接: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 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3130869.html