题目大意:

给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相连接的一端必须是同颜色的。

解题思路:

可以用图论中欧拉路的知识来解这道题,首先可以把木棒两端看成节点,把木棒看成边,这样相同的颜色就是同一个节点

问题便转化为:给定一个图,是否存在一笔画”经过涂中每一点,每条边一次。

这样就是求图中是否存在欧拉路Euler-Path

关于度数的判断方法:

节点的度用颜色出现次数来统计,如样例中,蓝色blue出现三次(不管是出度还是入度),那么blue结点的度就为3,同样地,我们也可以通过输入得到其他全部结点的度,于是,我们有:

Magenta=2

Blue=3

Red=2

Violet=1

Cyan=2

用一个一维数组就能记录了,然后分别模2,就能判断颜色结点的奇偶性

只要奇度数的结点数的个数=1或>=3,即使图连通,也一定不存在欧拉路径

Trie树+并查集+欧拉路径

#include<cstdio>
#include<cstdlib>
#define maxn 500010
typedef struct Trie{
int pos;
struct Trie *next[];
}Trie,*trie;
trie root;
int k=,fa[maxn],d[maxn];
void Init(trie &p)
{
p=(trie)malloc(sizeof(Trie));
for(int i=;i<;i++) p->next[i]=NULL;
p->pos=;
}//建Trie树,返回单词编号
int Build(trie &p,char *s,int depth)
{
if(!s[depth]){
if(p->pos) return p->pos;
p->pos=++k;
fa[k]=k,d[k]=;//初始化祖先为自身,度数为0
return k;
}//q不能定义为全局变量
trie q=p->next[s[depth]-'a'];
if(q==NULL){
Init(q);
p->next[s[depth]-'a']=q;
}
return Build(q,s,depth+);
}
int Findset(int x)
{
if(fa[x]==x) return x;
return fa[x]=Findset(fa[x]);
}
void Union(int u,int v)
{
int x=Findset(u);
int y=Findset(v);
if(x!=y) fa[x]=y;
}
int main()
{
Init(root);
char s[],t[];
while(scanf("%s%s",s,t)!=EOF){
int x=Build(root,s,);
int y=Build(root,t,);
Union(x,y);
d[x]++,d[y]++;
}
int scc=,odd=;
for(int i=;i<=k;i++){
if(fa[i]==i) scc++;//不连通
if(d[i]&) odd++;//奇度节点
}
if(scc>||odd>) puts("Impossible");
else puts("Possible");
return ;
}

离散化+并查集+欧拉路径

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500010
using namespace std;
int num[maxn],fa[maxn];
int idxc=,idxw=,cnt; struct Wood{
char left[],right[];
}wood[maxn/];
struct Node{
char col[];
bool operator<(const Node tmp)const{
if(strcmp(col,tmp.col)<=)
return true;
return false;
}
}node[maxn];
//二分查找颜色对应离散的编号
int Binary_Search(char *col){
int l=,r=cnt+;
while(r-l>){
int mid=(r+l)/;
if(strcmp(node[mid].col,col)<=) l=mid;
else r=mid;
}
return l;
}
int Findset(int x)
{
if(fa[x]!=x)
fa[x]=Findset(fa[x]);
return fa[x];
} int main()
{
char s1[],s2[];
while(scanf("%s%s",wood[idxw].left,wood[idxw].right)!=EOF){
strcpy(node[idxc++].col,wood[idxw].left);
strcpy(node[idxc++].col,wood[idxw].right);
idxw++;
}
sort(node+,node+idxc);
memset(num,,sizeof(num));
num[]++,cnt=;
for(int i=;i<idxc;i++){//进行离散处理,同时统计每种颜色出现的个数
if(strcmp(node[i].col,node[i-].col)!=){
strcpy(node[++cnt].col,node[i].col);
num[cnt]++;//颜色不同保留下来
}
else num[cnt]++;//颜色相同直接计数
}
for(int i=;i<maxn;i++) fa[i]=i;
for(int i=;i<idxw;i++){
int u=Binary_Search(wood[i].left);
int v=Binary_Search(wood[i].right);
int x=Findset(u),y=Findset(v);
if(x!=y) fa[x]=y;
}
int scc=,odd=;//cnt是节点编号,也是节点个数
for(int i=;i<=cnt;i++){
if(fa[i]==i) scc++;
if(num[i]%) odd++;
}
if(idxw==||(scc==&&(odd==||odd==))) printf("Possible\n");
else printf("Impossible\n");
}

PKU 2513 Colored Sticks(并查集+Trie树+欧拉路径(回路))的更多相关文章

  1. POJ 2513 Colored Sticks(欧拉回路,字典树,并查集)

    题意:给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的.   无向图存在欧拉路的充要条件为: ①     图是连通的: ②     所有节 ...

  2. nyoj 230/poj 2513 彩色棒 并查集+字典树+欧拉回路

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=230 题意:给你许许多多的木棍,没条木棍两端有两种颜色,问你在将木棍相连时,接触的端点颜色 ...

  3. [欧拉] poj 2513 Colored Sticks

    主题链接: http://poj.org/problem? id=2513 Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Tota ...

  4. poj 2513 Colored Sticks(欧拉路径+并检查集合+特里)

    题目链接:poj 2513 Colored Sticks 题目大意:有N个木棍,每根木棍两端被涂上颜色.如今给定每一个木棍两端的颜色.不同木棍之间拼接须要颜色同样的 端才干够.问最后是否能将N个木棍拼 ...

  5. UVA1455 - Kingdom(并查集 + 线段树)

    UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...

  6. 【bzoj5133】[CodePlus2017年12月]白金元首与独舞 并查集+矩阵树定理

    题目描述 给定一个 $n\times m$ 的方格图,每个格子有 ↑.↓.←.→,表示从该格子能够走到相邻的哪个格子.有一些格子是空着的,需要填上四者之一,需要满足:最终的方格图中,从任意一个位置出发 ...

  7. 并查集&线段树&树状数组&排序二叉树

    超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...

  8. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  9. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

随机推荐

  1. HDU1717--小数化分数2

    这道题是将输入的小数(有可能是无限循环小数)来化为分数.刚開始看到以为枚举(千万不要嘲笑我),可是感觉不正确. 所以百度了小数化为分数的方法,然后看到了各种方法,原来是这这样,在这我採用的是小数化为分 ...

  2. C++ 智能指针学习

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  3. C++之函数模板

    C++之函数模板与模版函数 直接上代码:  C++ Code  12345678910111213141516171819202122232425262728293031323334353637383 ...

  4. 分页技巧__设计分页用的QueryHelper辅助对象

    分页技巧__设计分页用的QueryHelper辅助对象 FROM 必须 实体名 WHERE  可选 条件1 AND 条件2 AND ... 条件n ORDER BY 可选 属性1, 属性2, ... ...

  5. Sublime Text 更新后,Package Control 不见了的解决办法

           把红框内配置删掉就可以了! via:http://www.qdfuns.com/notes/14464/f6813e4e18ac31bd856fe17fc8772ebc.html PS: ...

  6. Oracle正式发布VirtualBox 5.0.22版本

    甲骨文(Oracle)正式发布了VirtualBox 5.0.22版本,该开源和跨平台虚拟化软件的最新维护版本已经面向所有支持平台开放,引入了诸多新特性和功能改善推荐用户尽早完成升级.新版本在Linu ...

  7. phpredis 中文手册和redis 教程

    phpredis 中文手册  :   http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697006.html 手册: http://www.cn ...

  8. python中的coding的格式书写形式

     # -*- coding:utf-8 -*-可以改写成以下各种形式:1,# -*- coding=utf-8 -*-2,# _*_ coding=utf-8 _*_3,# coding:utf-84 ...

  9. 【BZOJ4881】5月月赛D 线段游戏 树状数组+set

    Description quailty和tangjz正在玩一个关于线段的游戏.在平面上有n条线段,编号依次为1到n.其中第i条线段的两端点坐 标分别为(0,i)和(1,p_i),其中p_1,p_2,. ...

  10. 微信openid的单脚本获取 将 header 至自身,但是reques参数不同,响应也不同-----“单脚本APP”

    w 0-目的是封装成一个类.方法,方便在不同入口下,比如不是在微信公众号内而是在他人分享的url,获取opeid,且便于路由控制,将路由控制交给且仅交给codeigniter; 1-任何一个网站都可以 ...