题目大意:有个一无向图,给所有的边染色,如果一个点连接的边超过两个,那么最少要染一个白色和一个黑色,能否给整个图染色?不能输出“No solution”。

分析:引用连接 http://edward-mj.com/archives/445

首先构建dfs树,无向图dfs树具有的一大优点是该点只会向自己的祖先或子孙有非树边。

然后按深度交替染色。返祖边与自己的儿子涂同样的颜色。

如果dfs树中根结点度超过1,那么就找一条边染不同的颜色。

否则看根结点是否满足条件,如果不是,那么找一个与根结点相连的叶子,向上找到一个度大于2的点为止,将该路径上所以边反色,并且将根与该叶子的边反色。如果找不到度大于2的点,那么是奇环,无解。

ps.注意这组数据:

5
2 3 0
1 3 0
1 2 4 5 0
3 5 0
3 4 0

代码如下:

======================================================================================================================

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std; const int MAXN = ; int c[MAXN][MAXN], N;///保存边的颜色, N个点
int father[MAXN], nSon[MAXN];
vector<int> e[MAXN];///相连接的点 void DFS(int u, int color)
{
for(int i=; i<e[u].size(); i++)
{
if(c[u][e[u][i]] != -)
continue;///这条边已经被访问过 nSon[u]++;///子树数目加1
c[e[u][i]][u] = c[u][e[u][i]] = color; if(!nSon[e[u][i]])
{///如果不是连接的祖边
father[e[u][i]] = u;
DFS(e[u][i], color^);
}
}
} int main()
{
int i, j, x; scanf("%d", &N); for(i=; i<=N; i++)
{
while(scanf("%d", &x), x)
e[i].push_back(x);
} memset(c, -, sizeof(c)); for(i=; i<=N; i++)
{
if(nSon[i] || father[i] || e[i].size()==)
continue; ///没有父节点,也没有儿子节点,说明未被访问过
for(j=; j<e[i].size(); j++)
{///与根节点连接的第一个节点赋值为颜色0,后面的赋值为别的颜色
if(j==)
{
nSon[i]++, father[e[i][j]] = i;
c[i][e[i][j]] = c[e[i][j]][i] = ;
DFS(e[i][j], );
}
else if(c[i][e[i][j]] == -)
{///这条边未被访问过
nSon[i]++, father[e[i][j]] = i;
c[i][e[i][j]] = c[e[i][j]][i] = ;
DFS(e[i][j], );
}
} if(nSon[i] >= || e[i].size() == )
continue;
///如果根节点的子树数目小于2,或者只有一个子节点 for(j=; j<e[i].size(); j++)
{///从子节点往父节点查找一个节点有大于或等于两个子树的节点
///如果找到那么就把这条路径上的所有边取反,如果找不到,无解 x = e[i][j]; if(c[x][i] == )
break;///不需要取反也可以 while(father[x] != i && nSon[x] < )
x = father[x]; if(father[x] == i)
continue;///未找到这样的节点 x = e[i][j];
c[x][i] = c[i][x] = ;
while(nSon[x] < )
{///路径上的边取反
c[x][father[x]] = c[father[x]][x] = c[x][father[x]] ^ ;
x = father[x];
} break;
} if(j == e[i].size())
break;///无解
} if(i <= N)
printf("No solution\n");
else
{
for(i=; i<=N; i++)
{
for(j=; j<e[i].size(); j++)
printf("%d ", c[i][e[i][j]]+);
printf("0\n");
}
} return ;
}
/**
5
2 3 0
1 3 0
1 2 4 5 0
3 5 0
3 4 0
**/

Bridges painting - SGU 121(构造)的更多相关文章

  1. sgu 121. Bridges painting 列举情况 难度:1

    121. Bridges painting time limit per test: 0.25 sec. memory limit per test: 4096 KB New Berland cons ...

  2. SGU 121.Bridges painting

    原题地址 题意: 新百慕大由N个岛屿组成,在岛屿之间有一些连接它们的桥.在任意两个岛屿之间,最多只有一座桥连接它们.总统先生下达命令,要求给所有桥上色. 每一座桥能被染成 白色 或者 黑色. 每一个岛 ...

  3. Erasing Edges - SGU 136(构造多边形)

    题目大意:已知一个多边形上的每条边的中点,还原出来一个多边形. 分析:因为偶数是不固定的,所以可以为任意起点,奇数只有一个,可以所有中点加减算出来第一个点,然后就是简单的向量计算点的位置了...... ...

  4. SGU 分类

    http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...

  5. 今日SGU 5.28

    SGU 121 题意:给你一张图,问你每个顶点必须有黑白两条边(如果它的边数>=2),问你怎么染色,不行就输出no 收获:你会发现不行的情况只有一个单纯的奇数环的时候,反之我们交替染色即可 #i ...

  6. echarts地图 绘制部分上海市公交线路数据

    源代码地址 https://github.com/a1115040996/MyHTML/blob/gh-pages/echarts/roadMap.html 预览地址 https://a1115040 ...

  7. SGU 183. Painting the balls( dp )

    dp..dp(i, j)表示画两个点为i-j, i的最优答案. dp(i, j) = min{ dp(i-j, k) } + cost[i] (1≤k≤M-j) 令f(i, j) = min{dp(i ...

  8. sgu 183. Painting the balls 动态规划 难度:3

    183. Painting the balls time limit per test: 0.25 sec.memory limit per test: 4096 KB input: standard ...

  9. 构造 - SGU 109 Magic of David Copperfield II

    Magic of David Copperfield II Problem's Link Mean: 略 analyse: 若i+j为奇数则称(i,j)为奇格,否则称(i+j)为偶格,显然每一次报数后 ...

随机推荐

  1. Action<>和Func<>区别

    Action<>和Func<>其实都是委托的[代理]简写形式. 简单的委托写法: //普通的委托 public delegate void myDelegate(string ...

  2. 正则过滤html标签

    var html = "<p>好好学习,<br>天天向上</p>"; var re=/<[^>]+>/g; var text ...

  3. 关于移动div的具体实现(js)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Html5学习--canvas

    canvas元素的实际尺寸(宽度,高度)是由标签上的属性width和height来决定的. 这两个属性不设置时默认值为:宽度=300px,高度=150px. 如果在样式表里设置width和height ...

  5. A transition animation compatible Library.

    Android5.0之后为我们提供了许多炫酷的界面过渡效果,其中共享元素过渡也是很有亮点的一个效果,但这个效果只能在Android5.0之后使用,那今天我们就来将共享元素过渡效果兼容到Android4 ...

  6. 制作font-icon有感

    连日来有些空闲,趁着这闲余时间,我尝试亲自制作一些Font-Icon,让以后可以运用到工作中.但是基于本人水平有限,PS操作只能以非常基础来形容,而AI呢,根本就只会放大操作.在这过程真的非常感谢设计 ...

  7. Python 基础 字符串拼接 + if while for循环

    注释单行注释 #多行注释 ''' 三个单引号或者三个双引号 """ ''' 用三引号引住可以多行赋值 用户交互 input 字符串拼接 +  ""%( ...

  8. 【python之旅】python的基础二

    一.集合的操作 1.什么是集合?     集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重:把一个列表变成集合,就自动去重 关系测试:测试两组数据之前的交集,差集,并集等关系   2.常用 ...

  9. python中跟字符串相关的一些操作

    公司让用python自动生成代码,以前没看过python.所以匆匆的看了两天python就连猜带蒙就上马开干了..因此好多操作可能看的时候看懂了,用的时候知道有这么个东西,具体用法就忘记了..用到了就 ...

  10. uboot的mtd功能支持

    一.概述 1.MTD MTD是Flash的一种管理方法,将Flash划分成几个分区,便于管理. u-boot的MTD功能是在文件cmd_jffs2.c中实现的,由此我们可以知道怎样打开u-boot的M ...