hdu 4263

这道题目的意思的解释解释:

题目给出n个节点,m条边(小于n*n,使得n个节点都连通),k值。要求我们判断能否只用k条蓝色边(外加给定的任意条红色边)使得所有节点形成一个生成树(n-1条边把n个节点全部连起来)


题解:

在比赛的时候想出了一个错误的做法= =!结果一下午WA……

正确的是将蓝边和红边分别跑一边最小生成树(Kruscal算法),跑的时候记录有多少条边加了进来。

设counter_r为加进来的红边,counter_b为加进来的蓝边

则当k>=n-1- counter_r && k<= counter_b的时候便满足要求;

n-1-counter_r表示还需要至少这么多条蓝边才能构成生成树。(下限)如果k比这个还小的话,就没有足够的R可以使得整个图构成一个生成树。

counter_b则表示可以同时加进来的蓝边的最大个数。(上限)

对于介于上限与下限之间的k值:

若增大,即加多一条蓝边,则会产生环,这时候则可以删除一条多余的红边。

若减少,即减少一条蓝边,仍可以找到一条红边替代它的位置使整个图保持生成树的结构。

唔……其实思路是我同学告诉我的= =,也不知道有没有说清楚,若有其他理解,望留言告之楼主……

另外……Ps一则找不到结构体哪里出错的代码,求有心的同学发现之…………http://zhidao.baidu.com/question/469243984.html?quesup2


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxx = 1010;
int Find(int x,int father[])
{
    while(x!=father[x]) x = father[x];
    return x;
}
void Union(int r1, int r2, int& counter,int father[])
{
    int a = Find(r1,father);
    int b = Find(r2,father);
    if(a!=b)
    {
        counter++;
        father[a] = b;
    }
}
void ini(int n,int father[])
{
    for(int i=1; i<=n; i++)
        father[i] = i;
}
int main()
{
//    freopen("1007.txt","r",stdin);
    int n,m,k;
    int father_r[maxx];
    int father_b[maxx];
    while(scanf("%d %d %d",&n,&m,&k),n||m||k)
    {
        ini(n,father_r);
        ini(n,father_b);
        int counter_r,counter_b;
        counter_r = counter_b = 0;
        for(int i=1; i<=m; i++)
        {
            char ch=0;
            while(ch!='B'&&ch!='R')
                ch=getchar();
            int u,v;
            scanf("%d%d",&u,&v);
            if(ch=='B')
                Union(u,v,counter_b,father_b);
            else
                Union(u,v,counter_r,father_r);
        }
        if(k<=counter_b && k>=n-counter_r-1)
            printf("1\n");
        else
            printf("0\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值