码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5302 构造

时间:2015-10-02 18:40:20      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你一个无向图,它的边要么是黑色要么是白色,且图上的每个点最多与两个黑边两个白边相连。现在,Demon将图分成两部分,一部分包含所有的黑边,另一部分包括所有的白边,给你白边图中度为0的点的数量w0,度为1的点数w1,度为2的点数w2,与黑边图中度为0的点数b1,度为1的点数b1,度为2的点数b2,要你输出任意一个符合条件的原图,如果不能,输出-1

无论是黑边图,还是白边图,给出的度为0、1、2三种点的数量均>=1 w0+w1+w2==b0+b1+b2,输出图的点数最多为w0+w1+w2个;图中无重边,无自环;

因为 只要白边或者 黑边 度数为1的点 为奇数个 就一定是无解的,因为每个点的白度数和黑度数至多为2,

那么最小是3个点  无解  4点的话  只剩  1 2 1 1 2 1 特判

接下来的 就构造

 

处理白色的时候 1 2 3 4 5..n  前w2 个分别连接,然后 接下来 从(w2,w2+1)(w2+2,w2+3)...(w2+w1-2,w2+w1-1) 然后再让最大的那个奇数和1相连,为何等等解释

处理黑色的时候1 3 5...2 4 6.... 依照上面的方法连接, 但是最后一条 就是选择 最后一个数和1相连,这样一定是一组解,因为我们排完相邻的不会有在之前相交(n>=5) 那么最大的偶数也不会和1相交,于是就得到解了

解释上面为何使用最大的奇数,就是为了让2和最大的奇数他们放在中间,尽量早的使用,在处理黑色的时候就不会产生无解了,因为最少有一个是没有黑色边度数的,最后一个和1连的 取最后一个便是,因为n>=5最后一个一定是大偶数也不会是2 那么就一定存在一组解

技术分享
#include <iostream>
#include <algorithm>

#include <cstdio>
using namespace std;
const int maxn=2000*3;
int a[maxn];
int main()
{
    int w0,w1,w2,b1,b0,b2;
    int cas;
    scanf("%d",&cas);
    for(int cc=1; cc<=cas; cc++)
    {
         scanf("%d%d%d%d%d%d",&w0,&w1,&w2,&b0,&b1,&b2);
         if(w0==0||w1==0||w2==0||b0==0||b1==0||b2==0)while(true);
         if(w1&1||b1&1){
            puts("-1");continue;
         }
         int n=w0+w1+w2;
         if(n==4){
             puts("4");
             puts("1 2 0");
             puts("1 3 0");
             puts("4 2 1");
             puts("4 3 1");
             continue;
         }
         printf("%d\n",(w1+w2*2+b1+b2*2)/2 );
         for(int i=1;i<w2; i++)
            printf("%d %d 0\n",i,i+1);
         for(int i=0;i<w1-1;i+=2){
            printf("%d %d 0\n",w2+i,w2+i+1);
         }
         int id=(n-1)/2*2+1;
         printf("%d %d 0\n",1,id);
         int cnt=0;
         for(int i=1;i<=n; i+=2){
              a[cnt++]=i;
         }
         for(int i=2;i<=n; i+=2){
            a[cnt++]=i;
         }
         for(int i=0;i<b2-1; i++)
            printf("%d %d 1\n",a[i],a[i+1]);
         int d=0;
         for(int i=0; i<b1-1; i+=2){
            printf("%d %d 1\n",a[b2-1+i],a[b2+i]);
            d=max(d,b2+i);
         }
         for(int i=d+1; ; i++)
         if(a[i]!=id&&a[i]!=2){
             printf("%d %d 1\n",1,a[i]);break;
         }
    }
    return 0;
}
View Code

 

hdu5302 构造

标签:

原文地址:http://www.cnblogs.com/Opaser/p/4852467.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!