题目大意:

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

解题思路:

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

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

这样就是求图中是否存在欧拉路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. js获取url中指定参数的值(含带hash)

    function getUrlVars() { var vars = {}; var parts = window.location.href.replace(/[?&]+([^=&] ...

  2. mac下MAMP的安装和使用

    详情博客:https://my.oschina.net/laiconglin/blog/514139

  3. UE4打包程序没有声音-需要安装UE4PrereqSetup_x64.exe

    一个UE4工程打包之后,放到一台新机器,最好安装一下UE4自带的Prerequisites,否则可能会出现没有声音的问题 此安装程序位于WindowsNoEditor\Engine\Extras\Re ...

  4. 《C++ Primer Plus》第4章 学习笔记

    数组.结构和指针是C++的3中符合类型.数组可以在一个数据对象中存储多个同种类型的值.通过使用索引或下标,可以访问数组中各个元素.结构可以将多个不同类型的值存储在同一个数据对象中,可以使用成员关系运算 ...

  5. MapRecude

    任务:分析通话记录,查处每个手机号码有哪些打过来的号码 13510921776 10086 13710148751 10086 13914248991 10086 13510921776 137101 ...

  6. linux 定时备份mysql数据库

    首先要先搞清楚两个概念: ①.mysqldump,mysqldump是mysql的逻辑备份工具,它不是linux的命令,工作原理类似产生一些列sql语句,对数据库进行指定的逻辑备份. 最简洁的形式是: ...

  7. JS获取时间戳+C#水煎戳转换

    JS获取了当前毫秒的时间戳. var timestamp=new Date().getTime(); //第二种方法: //var timestamp = (new Date()).valueOf() ...

  8. andriod的apk文件相关的编译反编译工具

    1.smali-1.2.6.jar 用途:.smali文件 转成 classes.dex文件 说明:.smali文件,类似于.class文件,可以用普通文本编辑器查看和修改. 用法举例:命令行:jav ...

  9. Rete_algorithm

    https://en.wikipedia.org/wiki/Rete_algorithm https://en.wikipedia.org/wiki/Rete_algorithm The Rete a ...

  10. vue-router路由懒加载

    正常配置 import Vue from 'vue' import Router from 'vue-router' import Login from '@/components/pages/log ...