/*
*State: HDU4263    453MS    3784K    1452 B    C++
*题目大意:
*        有一个无向无权图,只含有红边跟蓝边,判断是否它有一棵
*        最小生成树含有确定的k条蓝边。
*解题思路:
*        求一遍含蓝边最多的最小生成树,其中蓝边数为Max, 求一遍
*        含蓝边最少的最小生成树,其中蓝边数为Min.如果k值处于[Min, Max]
*        这个闭区间里面,那么该图含有题目要求的MST.
*        为什么是这样呢:因为这两棵极端的MST合并在一起只有两种
*        情况,1、就是只含有蓝边的环,这时候删掉一条蓝边,2、另一种情况
*        是含有红边跟蓝边的环,这时候每删去一条红边,那么当前的MST的
*        蓝边数就上升1,所以MST含有蓝边数是在[Min, Max]这个区间中。
*/
View Code
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXE = 1000005;
const int MAXN = 1005;
typedef struct _edge
{
    int u, v, w;
}E;

E edge[MAXE];
int fa[MAXN];

int findSet(int x)
{
    if(x != fa[x])
        fa[x] = findSet(fa[x]);
    return fa[x];
}

bool Union(int x, int y)
{
    int a = findSet(x);
    int b = findSet(y);
    if(a == b)
        return false;
    fa[b] = a;
    return true;
}

void initSet()
{
    for(int i = 0; i < MAXN; i++)
        fa[i] = i;
}

bool cmp1(const E &a, const E &b)
{
    return a.w < b.w;
}

bool cmp2(const E &a, const E &b)
{
    return a.w > b.w;
}

int main(void)
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int n, m, k;
    while(scanf("%d %d %d", &n, &m, &k), n || m || k)
    {
        
        int u, v, w;
        char op[5];
        for(int i = 0; i < m; i++)
        {
            scanf("%s %d %d", op, &u, &v);
            if(op[0] == 'B')
            {
                edge[i].u = u, edge[i].v = v;
                edge[i].w = 1;
            }
            else
            {
                edge[i].u = u, edge[i].v = v;
                edge[i].w = 0;
            }
        }
        initSet();
        int Min = 0, Max = 0;
        sort(edge, edge + m, cmp1);
        for(int i = 0; i < m; i++)
        {
            if(Union(edge[i].u, edge[i].v) && edge[i].w)
                Min++;
        }
        initSet();
        sort(edge, edge + m, cmp2);
        for(int i = 0; i < m; i++)
        {
            if(Union(edge[i].u, edge[i].v) && edge[i].w)
                Max++;
        }
        if(k >= Min && k <= Max)
            printf("1\n");
        else
            printf("0\n");
    }
    return 0;
}
posted on 2012-08-25 21:31  cchun  阅读(337)  评论(0编辑  收藏  举报