zoukankan      html  css  js  c++  java
  • UCIPC2012Red/Blue Spanning Tree解题报告

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4263

    杭电热身赛的题,属于简单题,两次Kruskal算法,先把所有的红边加完,红边可以保证一部分的图是联通的,然后加蓝边构成生成树,那么这些蓝边就是整个生成树当中必须要有的边(其实不是因为这些边必须要有,因为这些边连的点必须要加到生成树里,所以必须要有一定数量的蓝边,可能这些蓝边的选择方案有很多,但是数量是一定的),然后把图还原,把原来必须的蓝边先加上,再一直加没有用过的蓝边,最后看加的蓝边的数量是不是>=k如果满足则能有方案做到,否则不能。

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define N 1005
      5 using namespace std;
      6 int f[N];
      7 int n;
      8 bool used[N*N];
      9 struct edge
     10 {
     11     int u,v;
     12 };
     13 void init()
     14 {
     15     int i;
     16     for(i=1;i<=n;i++)
     17     f[i]=i;
     18     memset(used,0,sizeof(used));
     19 }
     20 int find(int i)
     21 {
     22     if(i!=f[i])
     23     {
     24         f[i]=find(f[i]);
     25     }
     26     return f[i];
     27 }
     28 void uni(int x,int y)
     29 {
     30     int t1=find(x);
     31     int t2=find(y);
     32     if(t1!=t2)
     33     f[t2]=t1;
     34 }
     35 edge R[N*N],B[N*N];
     36 int main()
     37 {
     38     int m,k,i,j,a,b;
     39     char s[2];
     40     int cnt1,cnt2;
     41     while(scanf("%d%d%d",&n,&m,&k)&&(n||m||k))
     42     {
     43         cnt1=cnt2=0;
     44         init();
     45         for(i=1;i<=m;i++)
     46         {
     47             scanf("%s%d%d",s,&a,&b);
     48             if(s[0]=='R')
     49             {
     50                 R[cnt1].u=a;
     51                 R[cnt1++].v=b;
     52             }
     53             else
     54             {
     55                 B[cnt2].u=a;
     56                 B[cnt2++].v=b;
     57             }
     58         }
     59         if(cnt2<k)
     60         {
     61             printf("0\n");
     62             continue;
     63         }
     64         //printf("%d %d\n",cnt1,cnt2);
     65         for(i=0;i<cnt1;i++)
     66         {
     67             uni(R[i].u,R[i].v);
     68         }
     69         int num=0;
     70         int num1=0;
     71         for(i=0;i<cnt2;i++)
     72         {
     73             if(find(B[i].u)!=find(B[i].v))
     74             {
     75                 num++;
     76                 uni(B[i].u,B[i].v);
     77                 used[i]=true;
     78             }
     79         }
     80         if(num>k)//如果必须加的蓝边的数量>k那就意味着无解了
     81         {
     82             printf("0\n");
     83             continue;
     84         }
     85         for(i=1;i<=n;i++)
     86         {
     87             f[i]=i;
     88         }
     89         for(i=0;i<cnt2;i++)
     90         {
     91             if(used[i])
     92             {
     93                 uni(B[i].u,B[i].v);
     94             }
     95         }
     96         for(i=0;i<cnt2;i++)
     97         {
     98             if(!used[i]&&find(B[i].u)!=find(B[i].v))
     99             {
    100                 num++;
    101                 uni(B[i].u,B[i].v);
    102             }
    103         }
    104         if(num>=k)
    105         printf("1\n");
    106         else
    107         printf("0\n");
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    机器学习【九】数据表达与特征工程
    机器学习【八】数据预处理、降维、特征提取及聚类
    机器学习【七】神经网络
    机器学习【六】支持向量机SVM——专治线性不可分
    机器学习【五】随机森林
    机器学习【四】决策树
    单片机简介 & 点亮LED & 流水灯 & 电路基础
    PHP表单
    机器学习【三】朴素贝叶斯
    PHP 【六】
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2657188.html
Copyright © 2011-2022 走看看