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. 解压压缩文件报错gzip: stdin: not in gzip format tar: Child returned status 1 tar: Error is not recoverable: exiting now

    压缩包是直接weget 后面加官网上的tar包地址获取的  [root@xuegod43 ~]# tar -zxvf /home/hadoop/hadoop-2.6.5-src.tar.gz gzip ...

  2. redis SERVER INSTALL WINDOWS SERVICE

    以管理 员身份 运行 CMD 命令,进入redis所在目录,并运行下 脚本redis-server --service-install redis.windows-service.conf --log ...

  3. 苹果ios用js的Date()出现NaN问题解决办法

    原文:苹果ios用js的Date()出现NaN问题解决办法 ios使用如下方法获得NaN,安卓手机则是正常计算,解决方法是换个这个时间的格式 new Date("2017-04-28 23: ...

  4. 赵海军获任中芯国际CEO 邱慈云留任副董事长、非执行董事(年薪40万美元+300万股票的认购权)

    集微网消息,中芯国际今日宣布,由赵海军博士接替邱慈云博士担任中芯国际首席执行官,邱慈云博士将留任副董事长.非执行董事,并于2017年6月30日前担任公司全职顾问,于当日生效.邱博士将与赵博士紧密合作, ...

  5. Redaht7/Oracle Linux7 + ORA11g : ohasd fails to start(Doc ID 1959008.1)

    APPLIES TO: Oracle Database - Standard Edition - Version 11.2.0.4 to 12.1.0.1 [Release 11.2 to 12.1] ...

  6. 【JS 笔记】比较操作符之大小与记录

    1,字符串比较 字符串比较则是使用基于标准字典的 Unicode 值来进行比较的. 对于两个拥有相同字符顺序,相同长度,并且每个字符的位置都匹配的字符串,应该使用严格比较运算符. 下例的比较中可能因为 ...

  7. 了解Service

    多线程编程: 线程的基本用法: 1. class MyThread extends Thread{ @Override public void run() { //处理具体逻辑 } } new MyT ...

  8. 使用Visual Studio开发Python

    Python优秀的集成开发环境有PyCharm,Visual Studio Code等,当然你仍然可以使用Visual Studio进行开发.如果你熟悉Visual Studio,使用Visual S ...

  9. QT中的各种对话框

    大家可以参见QT中各种MessageBox的使用的这篇文章 界面效果图如下,大家可以用代码自己操作 diglog.h #ifndef DIALOG_H #define DIALOG_H #includ ...

  10. 【DRP】-Dao层常用功能代码:增删改查

    本系列博客内容为:做DRP系统中Dao层常用功能. 该项目采用MVC架构 C(Controller)控制器,主要职责;1.取得表单参数:2.调用业务逻辑:3.转向页面 M(Model)模型,主要职责: ...