题目大意:有个一无向图,给所有的边染色,如果一个点连接的边超过两个,那么最少要染一个白色和一个黑色,能否给整个图染色?不能输出“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. iOS pop使用通知传值

    iOS pop回父级页面,使用通知传值 输入所要发送的信息 ,同时将label的值通过button方法调用传递, - (IBAction)buttonClick:(id)sender { //添加 字 ...

  2. 7-1 DBA顾问培训内容@20141230

    1, 逻辑读还是物理读? 查询语句的实际执行计划. F5 预计执行计划. --如何产生实际执行计划 ??. --Session收集指令.   workload repository report fo ...

  3. jQuery 遍历后代

    后代是子.孙.曾孙等等. 通过 jQuery,您能够向下遍历 DOM 树,以查找元素的后代. 向下遍历 DOM 树 下面是两个用于向下遍历 DOM 树的 jQuery 方法: children() f ...

  4. thinkphp关联查询(多表查询)

    1.Table方法:定义要操作的数据表名称,可以动态改变当前操作的数据表名称,需要写数据表的全名,包含前缀,可以使用别名, 例如: $Model->Table('think_user user' ...

  5. JVM学习笔记-运行时数据区

    不同于C,C++程序,Java程序的内存管理工作由Java虚拟机(JVM)接管,这减低了java程序员的负担,但如果出现内存泄露与溢出问题如报OutOfMemory,StackOverFlow异常错误 ...

  6. js 组件的写法

    var Test1 = function(){ var name = ""; this.setName = function(username){ name = username; ...

  7. demo_02 less

    html 中的代码<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> &l ...

  8. yum命令学习

    yum配置文件 /etc/yum.conf yum check-update检查一下有无更新 每天都要(设置定时任务todo) 1.列出所有可更新的软件清单---yum check-update 2. ...

  9. 过滤器(Filter)

    day21 过滤器概述 1 什么是过滤器 过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servlet时,会先执行部署在这个 ...

  10. struts中如何将前台的值能在action中获取到

    如何获取值----三种方式(属性驱动,对象驱动,模型驱动)  A:属性驱动 必须生成get,set方法  B:对象驱动 给对象也必须生成get,set方法  c模型驱动 模型驱动需要action去实现 ...