[2015hdu多校联赛补题]hdu5302 Connect the Graph

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5302

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

(注1:无论是黑边图,还是白边图,给出的度为0、1、2三种点的数量均>=1;

 注2:w0+w1+w2==b0+b1+b2,输出图的点数最多为w0+w1+w2个;

 注3:图中无重边,无自环;

解:构造题

考虑每条边对应两度,那么w1或b1为奇数一定无解

排除以上情况,有w1>=2 && b1>=2,将二度的点排成一排,顺次链接起来,然后将首尾分别和一个一度点相连,剩下的一度点两两互相连接即可

这样我们就可以解决黑图或白图,考虑上述构造方法每个点只和相邻的点连接,我们在构造完一图之后,另外一图只需要稍微打乱下点的顺序即可

for example:

1 2 3 4 5 -> 1 4 2 5 3

另外n==4的时候需要特判一下。。。

 1 /*
 2  * Problem: hdu5302 Connect the Graph 
 3  * Author:  SHJWUDP
 4  * Created Time:  2015/8/10 星期一 19:24:32
 5  * File Name: 1006.cpp
 6  * State: Accepted
 7  * Memo: 构造
 8  */
 9 #include <iostream>
10 #include <cstdio>
11 #include <vector>
12 #include <cstring>
13 #include <algorithm>
14 
15 using namespace std;
16 
17 int main() {
18 #ifndef ONLINE_JUDGE
19     freopen("in", "r", stdin);
20     //freopen("out", "w", stdout);
21 #endif
22     int T;
23     scanf("%d", &T);
24     while(T--) {
25         vector<int> w(3), b(3);
26         for(int i=0; i<3; i++) scanf("%d", &w[i]);
27         for(int i=0; i<3; i++) scanf("%d", &b[i]);
28         if((w[1] & 1) || (b[1] & 1)) {
29             puts("-1"); continue;
30         }
31         int n=w[0]+w[1]+w[2];
32         if(n<=4) {
33             puts("4
1 2 0
1 3 0
2 3 1
3 4 1"); continue;    
34         }
35         int m1=w[2]+w[1]/2;
36         int m2=b[2]+b[1]/2;
37         printf("%d
", m1+m2);
38         int nw=1;
39         w[2]++;
40         while(w[2]--) {
41             printf("%d %d 0
", nw, nw+1); nw++;
42         }
43         w[1]-=2; nw++;
44         while(w[1]) {
45             printf("%d %d 0
", nw, nw+1); nw+=2;
46             w[1]-=2;
47         }
48         vector<int> table(n+1);
49         int pos=1;
50         for(int i=1; i<=n; i+=2) table[pos++]=i;
51         for(int i=2; i<=n; i+=2) table[pos++]=i;
52         int nb=1;
53         b[2]++;
54         while(b[2]--) {
55             printf("%d %d 1
", table[nb], table[nb+1]); nb++;
56         }
57         b[1]-=2; nb++;
58         while(b[1]) {
59             printf("%d %d 1
", table[nb], table[nb+1]); nb+=2;
60             b[1]-=2;
61         }
62     }
63     return 0;
64 }
hdu5302
原文地址:https://www.cnblogs.com/shjwudp/p/4719279.html