poj 2513--Colored Sticks
来源:互联网 发布:淘宝网广场舞服装新款 编辑:程序博客网 时间:2024/06/15 20:49
题意:给出一些列两端带有颜色的不同棍子,问这些棍子首尾相连(当然要颜色相同)是否能形成链状。
解决方案:
- 根据输入将棍子当成边,两端颜色为点,构成无向图。
- 题目要求计算图中是否存在欧拉路, 存在欧拉路 => 图为连通图且,除了链两端点其他节点的度数皆为偶数。
- 若两端节点相同,则度数都为偶,若不同则只存在两个奇数度数节点。同样可证明上述为必要条件,可见图论教材。简单来说,若存在一条最长链W只经过每条边依次,则包括端点的边必定都在链W里,若两端点为同一节点,则此链为局部欧拉环路。因为图连通,则必存在一点可以 到此链,则组成更大一条链。若此链端点不同,则奇数度数顶点都在链中,同样可以加入不在链中的点,因为新加点度数必为偶数,则还可以继续加新点。(证明不充分)。
*****初始化个颜色为不同集合,使用并查集,当新加入边时,查找各自根节点,若根节点不同,则把高度 较小的根节点的父节点置为另一根节点,在查找根节点过程中同时路径压缩,时路径中的所有点的父节点都指向根节点。保存边,在所有颜色输入以后再初始化fa数组更快。
#include<cstdio>#include<cstring>using namespace std;#define maxS 26#define maxN 400000#define maxC 500000#define maxM 12struct node{ int colorNo; int sons[maxS];}trie[maxN];int colorNum;int trieIndex;int edgesNum;int degree[maxC];int fa[maxC];int height[maxC];int edges[250000][2];int trieInsert(char* color){ int now = 0; int next; bool IsNewColor = false; while(*color) { next = *color-'a'; if(!trie[now].sons[next]) { trie[now].sons[next] = ++trieIndex; IsNewColor = true; } now = trie[now].sons[next]; color++; } if(IsNewColor) { return (trie[now].colorNo = colorNum++); } else { return trie[now].colorNo; }}int findSet(int x){ if(x != fa[x]) fa[x] = findSet(fa[x]); //路径压缩,使路径上的点全部指向x的根节点 return fa[x];}int union_find(){ int i; for(i = 0;i < colorNum;i++) fa[i] = i; for(i = 0;i < edgesNum;i++) { int xRoot = findSet(edges[i][0]); int yRoot = findSet(edges[i][1]); if(height[yRoot] > height[xRoot]) { fa[xRoot] = yRoot; } else { fa[yRoot] = xRoot; if(height[xRoot] == height[yRoot]) height[xRoot]++; } } return 0;}int trieCheck(char* color,char* color_adj){ int tmpColorNo[2]; tmpColorNo[0] = trieInsert(color); tmpColorNo[1] = trieInsert(color_adj); if(tmpColorNo[0] != tmpColorNo[1]) { degree[tmpColorNo[0]]++; degree[tmpColorNo[1]]++; edges[edgesNum][0] = tmpColorNo[0]; edges[edgesNum++][1] = tmpColorNo[1]; } return 0;}bool judge(){ int i; int oddNum = 0; for(i = 0;i < colorNum;i++) { if(fa[i] != fa[0]) return false; if(degree[i]%2) { oddNum++; if(oddNum > 2) return false; } } return true;}int main(){ char colorTmp1[maxM],colorTmp2[maxM]; trieIndex = 0; colorNum = 0; edgesNum = 0; while(~scanf("%s%s",colorTmp1,colorTmp2)) { trieCheck(colorTmp1,colorTmp2); } union_find(); if(!colorNum||judge()) //此题有零输入情况 { printf("Possible\n"); } else { printf("Impossible\n"); } return 0;}
0 0
- POJ 2513 Colored Sticks
- poj 2513 Colored Sticks
- POJ 2513 Colored Sticks
- poj 2513 colored sticks
- Poj 2513 Colored Sticks
- POJ 2513 Colored Sticks
- POJ 2513 Colored Sticks
- POJ 2513 Colored Sticks
- poj 2513 Colored Sticks
- poj 2513 Colored Sticks
- POJ 2513 Colored Sticks
- POJ 2513 Colored Sticks
- Poj 2513 Colored Sticks
- poj 2513 Colored Sticks
- POJ 2513 Colored Sticks
- POJ 2513 Colored Sticks
- poj 2513 Colored Sticks
- POJ 2513 Colored Sticks
- MPEG2-TS音视频同步原理(PCR dts pts)
- Java学习笔记(十)
- inno setup 5 添加快捷方式默认选中
- FAST FW54R V6.1拆解照片
- Java网络连接之HttpURLConnection与HttpClient 区别及联系
- poj 2513--Colored Sticks
- java1.7与Android中的文件I/O操作(草稿)
- genymotion安装教程:安卓模拟器genymotion安装步骤详解
- R语言:R-hive-mysql-php 可视化
- 苹果iPhone 6缺货幕后:渠道商饥饿营销
- 五种典型开发周期模型(瀑布、V、原型化、螺旋、迭代)
- C#网络编程中结构体与字节数组的转换
- 转 传统MySQL+ Memcached架构遇到的问题
- Java中super关键字的三种用法