http://codeforces.com/gym/101257/problem/B

题意:给出两棵叶子数一样的树,在将叶子合并之后,对这个图进行染色,相邻的结点颜色不能相同,问最少需要染的颜色数,并输出合并叶子的方案。

思路:画了好几个图找了下规律,发现对于任意一个这样的图,最多只需要染三种颜色,最少是染两种颜色。

如果合并后的图,每一条从一棵树的根节点走到另一棵树的根节点的路径长度的奇偶性相同,那么这个时候就是只需要染两种颜色。

剩下的情况就是染三种颜色了。

对于每棵树,随便找一个不是叶子结点当做根节点往下DFS(因为无论选择哪个点,弄出来的路径长度奇偶性数量是相同的)求出每棵树路径长度为奇数的个数和为偶数的个数,然后分别记录后就可以求解了。

有两种情况染两种颜色:第一棵树的奇数 = 第二棵树的奇数,第一棵树的奇数 = 第二棵树的偶数。(少考虑了第二种情况,大概以为推论是错的)。然后按要求输出。

 #include <bits/stdc++.h>
using namespace std;
#define N 200010
#define INF 0x3f3f3f3f
const double eps = 1e-;
typedef long long LL;
struct Edge {
int v, nxt;
} edge[N*];
int head[N], tot, col[N], deg1[N], deg2[N], dis1[N], dis2[N], ans, n1, n2;
vector<int> leaf1, leaf2, d1, d2, e1, e2; void Add(int u, int v) {
edge[tot] = (Edge) {v, head[u]}; head[u] = tot++;
edge[tot] = (Edge) {u, head[v]}; head[v] = tot++;
} void dfs(int u, int fa, int *dis) {
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(v == fa) continue;
dis[v] = dis[u] + ;
dfs(v, u, dis);
}
}
//
int main() {
memset(head, -, sizeof(head)); tot = ;
scanf("%d", &n1);
int rt1 = -, rt2 = -;
for(int i = ; i < n1; i++) {
int u, v; scanf("%d%d", &u, &v);
Add(u, v); deg1[u]++; deg1[v]++;
}
for(int i = ; i <= n1; i++)
if(deg1[i] == ) leaf1.push_back(i); // 度为1的点叶子
else rt1 = i;
dis1[rt1] = ; // 随便挑一个当根结点然后往下DFS求出距离,因为距离的奇偶是确定的
dfs(rt1, -, dis1); memset(head, -, sizeof(head)); tot = ;
scanf("%d", &n2);
for(int i = ; i < n2; i++) {
int u, v; scanf("%d%d", &u, &v);
Add(u, v); deg2[u]++; deg2[v]++;
}
for(int i = ; i <= n2; i++)
if(deg2[i] == ) leaf2.push_back(i);
else rt2 = i;
dis2[rt2] = ;
dfs(rt2, -, dis2); int odd1, eve1, odd2, eve2;
odd1 = eve1 = odd2 = eve2 = ;
int sz = leaf1.size();
for(int i = ; i < sz; i++) { // 求两棵树分别的奇偶距离数
if(dis1[leaf1[i]] & ) odd1++, d1.push_back(leaf1[i]);
else eve1++, e1.push_back(leaf1[i]);
if(dis2[leaf2[i]] & ) odd2++, d2.push_back(leaf2[i]);
else eve2++, e2.push_back(leaf2[i]);
}
if(odd1 == odd2) { // 如果第一棵树的奇数距离和第二棵树的奇数(或偶数)距离相等,那么可以只涂两种颜色
puts("");
for(int i = ; i < odd1; i++)
printf("%d %d\n", d1[i], d2[i]);
for(int i = ; i < eve1; i++)
printf("%d %d\n", e1[i], e2[i]);
} else if(odd1 == eve2) {
puts("");
for(int i = ; i < odd1; i++)
printf("%d %d\n", d1[i], e2[i]);
for(int i = ; i < eve1; i++)
printf("%d %d\n", e1[i], d2[i]);
} else { // 否则最多只需要三种,可以随便输出
int a1 = , b1 = , a2 = , b2 = ;
puts("");
for(int i = ; i < sz; i++) {
if(a1 == odd1) printf("%d ", e1[b1++]);
else printf("%d ", d1[a1++]);
if(a2 == odd2) printf("%d\n", e2[b2++]);
else printf("%d\n", d2[a2++]);
}
}
return ;
}

Gym 101257B:2Trees(DFS+思维)的更多相关文章

  1. hdu6035[dfs+思维] 2017多校1

    /*hdu6035[dfs+思维] 2017多校1*/ //合并色块, 妙啊妙啊 #include<bits/stdc++.h> using namespace std; ; const ...

  2. D. Eternal Victory(dfs + 思维)

    D. Eternal Victory time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. Gym 101128A Promotions(思维 + dfs)题解

    题意:给一有向图,如果A指向B,则A是B的上级.一直i要升职那么他的上级必须都升职.现在给你一个升职人数的区间[a, b],问你升职a人时几个人必被升职,b时几个人必升职,b时几个人没有可能被升职. ...

  4. Gym 100463D Evil DFS

    Evil Time Limit: 5 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Descri ...

  5. Codeforces Gym 100463D Evil DFS

    Evil Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Descr ...

  6. Codeforces Gym101246G:Revolutionary Roads(DFS+思维)

    http://codeforces.com/gym/101246/problem/G 题意:有一个n个点m条边的有向图,现在可以修改某一条有向边使得其为无向边,问修改哪些边可以使得修改后的强连通分量的 ...

  7. Gym 102346A Artwork dfs

    Artwork Gym - 102346A 题意:给n*m的地图,入口是(0,0),出口是(n,m),其中有k个监视器,坐标是(xi,yi),监视半径是r,问一个人能不能不被监视到,从起点到终点. 如 ...

  8. Artwork (Gym - 102346A)【DFS、连通块】

    Artwork (Gym - 102346A) 题目链接 算法 DFS,连通块 时间复杂度:O(k*n + k * k) 1.这道题就是让你判断从(0,0)到(m,n),避开中途所有的传感器(传感器的 ...

  9. Codeforces Gym 100650B Countdown DFS

    Problem B: CountdownTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/conte ...

随机推荐

  1. 2-19-使用apache搭建web网站

    1 搭建一台测试web服务器 案例: 部门内部搭建一台WEB服务器,采用的IP地址和端口为192.168.10.34:80,首页采用index.html 文件.管理员E-mail地址为 xuegod@ ...

  2. C++ Boost 学习资源列表

    文档书籍下载 Boost Documentation Boost代码下载       优秀网站导航 Boost官方网站 Boost中文站 Boost Consulting     专题资源报告 Lin ...

  3. 使用委托实现c#,窗体与窗体之间的传值

    主界面: Form1中的代码: namespace _06委托练习_窗体传值{    public partial class Form1 : Form    {        public Form ...

  4. php将秒转换为 分:秒 函数

    php将秒转换为 分:秒 函数 /** * 将秒转换为 分:秒 * s int 秒数 */ function s_to_hs($s=0){ //计算分钟 //算法:将秒数除以60,然后下舍入,既得到分 ...

  5. hexo-theme-next

    Hexo Next github主页:https://github.com/iissnan/hexo-theme-next 官网地址:http://theme-next.iissnan.com/ 一篇 ...

  6. [原译]一步步教你制作WPF圆形玻璃按钮

    原文:[原译]一步步教你制作WPF圆形玻璃按钮 图1 1.介绍 从我开始使用vista的时候,我就非常喜欢它的圆形玻璃按钮.WPF最好的一个方面就是允许自定义任何控件的样式.用了一段时间的Micros ...

  7. 【全面解禁!真正的Expression Blend实战开发技巧】第二章 你好,UI设计师

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第二章 你好,UI设计师 你好,UI设计师 曾几何时我从没想过要与艺术家打交道,但是Silverlight改变了这一切.UI设计师 ...

  8. QT 自定义消息(超级简单的一个例子)

    #define TEST_EVENT QEvent::User + 100   class CVxActuatorMain : public QMainWindow {   protected:    ...

  9. 仿win7窗体自动顶部最大化左侧右侧半屏效果(改写nativeEvent,使用AdjustWindowRectEx)

    #include "HMainWindow.h" #include <QApplication> #ifdef Q_OS_WIN #include <qt_win ...

  10. 邮件带附件和html格式

    1. 发送有附件的邮件需要添加一个附件类Attachment,这个附件可以为文件和图片: Attachment attach = new Attachment(“文件路径”");//文件 A ...