-和尚-

导航

HDU 4263 Red/Blue Spanning Tree

Description

Given an undirected, unweighted, connected graph, where each edge is colored either blue or red, determine whether a spanning tree with exactly k blue edges exists.

Input

There will be several test cases in the input. Each test case will begin with a line with three integers:
n m k
Where n (2≤n≤1,000) is the number of nodes in the graph, m (limited by the structure of the graph) is the number of edges in the graph, and k (0≤k<n) is the number of blue edges desired in the spanning tree.
Each of the next m lines will contain three elements, describing the edges:
c f t
Where c is a character, either capital ‘R’ or capital ‘B’, indicating the color of the edge, and f and t are integers (1≤f,tntf) indicating the nodes that edge goes from and to. The graph is guaranteed to be connected, and there is guaranteed to be at most one edge between any pair of nodes.
The input will end with a line with three 0s.

Output

For each test case, output single line, containing 1 if it is possible to build a spanning tree with exactly k blue edges, and 0 if it is not possible. Output no extra spaces, and do not separate answers with blank lines.

Sample Input

3 3 2 B 1 2 B 2 3 R 3 1 2 1 1 R 1 2 0 0 0

Sample Output

1 0

这道题真的很不值,比赛的时候队友看错题目,搞得自己也没AC。后来比赛结束自己看题目才知道题意理解错了!一开始队友看题跟我说是找出所有的树(蓝边刚好为K条)然后输出有几条;这还真错了!原来真正的题意是,看图中的生成树是否有一颗树是蓝边为K条边的!有就输出1,没就输出0;这道题一开始我想到得是先找出最小生成树,记录其中的蓝边个数为sum1,再找出其中的最大生成树,找出其中的蓝边的条sum2,然后判断if(sum<=k&&sum2>=k)则存在,否则不存在这样的一棵树。这道题无非就是用Kruskal来求出它的最小和最大生成树!Kruskal无非就是并查集的知识!具体思想就不多说!

AC代码:

#include"stdio.h"

#include"stdlib.h"

typedef struct

{

    int v1,v2,cost;

}EE;

EE edg[500005];int n,m,p;

int cmp(const void *a,const void *b)

{

    EE *c=(EE *)a;

    EE *d=(EE *)b;

    return c->cost-d->cost;

}

int find(int *fa,int v)

{

    int t=v;

    while(fa[t]>=0)

        t=fa[t];

    return t;

}

int kur()

{

    int vf1,vf2,i,j,fa[1005],sum=0;

    for(i=1;i<=n;i++)

        fa[i]=-1;

    i=0;j=0;

    while(i<m&&j<n-1)

    {

        vf1=find(fa,edg[i].v1);

        vf2=find(fa,edg[i].v2);

        if(vf1!=vf2)

        {

            fa[vf2]=vf1;

            sum+=edg[i].cost;

            j++;

        }

        i++;

    }

    return sum;

}

int kur2()

{

    int vf1,vf2,i,j,fa[1005],sum=0;

    for(i=1;i<=n;i++)

        fa[i]=-1;

    i=m-1;j=n-2;

    while(i>=0&&j>=0)

    {

        vf1=find(fa,edg[i].v1);

        vf2=find(fa,edg[i].v2);

        if(vf1!=vf2)

        {

            fa[vf2]=vf1;

            sum+=edg[i].cost;

            j--;

        }

        i--;

    }

    return sum;

}

int main()

{

    int i,j,k,a1,a2;char ch;

    while(scanf("%d%d%d",&n,&m,&p),n||m||p)

    {

        for(i=0;i<m;i++)

        {

            getchar();

            scanf("%c%d%d",&ch,&j,&k);

            if(ch=='R')

                edg[i].cost=0,edg[i].v1=j,edg[i].v2=k;

            else

                edg[i].cost=1,edg[i].v1=j,edg[i].v2=k;

        }

        qsort(edg,m,sizeof(edg[0]),cmp);

        a1=kur();

        a2=kur2();

        if(a1<=p&&a2>=p)

            printf("1\n");

        else

            printf("0\n");

    }

    return 0;

}

从这一题当中我又知道了一个道理:比赛要多点看题目,自己也要看题目。

posted on 2012-08-27 15:30  -和尚-  阅读(246)  评论(0编辑  收藏  举报