您的位置:首页 > 其它

多校第二场 1003 hdu 5302 Connect the Graph(构造)

2015-07-26 15:34 519 查看
题目链接:

点击打开链接

题目大意:

给出一张图中的一些信息。包括与0,1,2条黑边相连的点的个数,与0,1,2条白边相连的点的个数。构造出一个这样的图。

题目分析:

首先我们设a[i]为连有i条白边的点的个数,b[i]为连有i条黑边的点的个数。

所以我们容易得到结论,a[1]和b[1]都不能使奇数,因为两条边每条白边能够贡献出的度数为2,所以白边的总度数一定是偶数,如果度数为1的点的个数为奇数,那么总度数一定是奇数,就与白边的总度数矛盾了!!

黑边与白边同理。

我们可以通过构建出一条链,得到2个度数为1的点和全部的度数为2的点,因为给出度数为1的点不可能小于1,那么也就是最小值就是2,那么我们构建这条链一定是合理的。对于黑边,我们需要标记奇偶点,因为不存在重边,所以我们在建黑边的时候采用奇偶点连边的方式来防止出现重边。

最后剩下的度数为1的边,找两个点白边相邻连边,黑边奇偶点连边。

最后得到的这个图就是满足题意的一个构造。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define MAX 1000007

using namespace std;

int t;
int a[5],b[5];
int d[MAX];

int main ( )
{
    scanf ( "%d" , &t );
    while ( t-- )
    {
        for ( int i = 0 ; i < 3 ; i++ )
            scanf ( "%d" , &a[i] );
        for ( int i = 0 ; i < 3 ; i++ )
            scanf ( "%d" , &b[i] );
        //获得点的总个数
        int sum = 0;
        for ( int i = 0 ; i < 3 ; i++ )
            sum += a[i];
        if ( (a[1]&1) || (b[1]&1) )
        {
            puts("-1");
            continue;
        }
        if ( sum == 4 )
        {
            puts("4\n1 2 0\n1 3 0\n2 3 1\n3 4 1");
            continue;
        }
        printf ( "%d\n" , a[1]/2+a[2]+b[1]/2+b[2] );
        int t = 1;
        //利用链构建出白边度数都为2,只有两端的点都只是1
        while ( a[2] != -1 )
        {
            printf ( "%d %d 0\n" , t , t+1 );
            t++;
            a[2]--;
        }
        t++;
        //除了链两端的点构建出其他的白边读书为1的点
        while ( a[1] != 2 )
        {
            printf ( "%d %d 0\n" , t , t+1 );
            t += 2;
            a[1] -= 2;
        }
        int tt = 0;
        //得到奇数点和偶数点,因为不能有重边,所以利用黑边建图时两个间隔
        for ( int i = 1 ; i <= sum ; i += 2 )
            d[tt++] = i;
        for ( int i = 2 ; i <= sum ; i += 2 )
            d[tt++] = i;

        t = 0;
        //构造出黑边度数为2的点
        while ( b[2] != -1 )
        {
            printf ( "%d %d 1\n" ,
                    min ( d[t] , d[t+1] ) , max ( d[t] , d[t+1]));
            t++;
            b[2]--;
        }
        t++;
        //构建除了那条链的两个端点以外的点
        while ( b[1]!= 2 )
        {
            printf ( "%d %d 1\n", min(d[t],d[t+1] ), max ( d[t],d[t+1]));
            t += 2;
            b[1] -= 2;
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: