标签:des style blog http color 使用
Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 29736 | Accepted: 7843 |
Description
Input
Output
Sample Input
blue red red violet cyan blue blue magenta magenta cyan
Sample Output
Possible
Hint
Source
每根木棒两端都有一种颜色,如果两根木棒一端有相同的颜色,则可以连在一块,给出一系列木棒的颜色,问这些木棒可不可以连成一条直线。
思想为建图,一种颜色为一个节点,不同的木棒相同的颜色是一个节点,如果能连城一条直线的话,那么所建的图一定是连通图,且从起点出发,每条边只能经过一次(直线就是这样),这就想到了欧拉通路。
欧拉通路 (欧拉迹)—通过图中每条边一次且仅一次,并且过每一顶点的通路。
对于无向图来说:
G有欧拉通路的充分必要条件为:G 连通,G中只有两个奇度顶点(它们分别是欧拉通路的两个端点)。
所以我们要解决两个问题:
1.怎样判断建的图是连通的?
2.怎样判断奇度顶点的个数?
对于第一个问题,采用并查集可以解决,只要所有的顶点都在一个集合里面,那么图一定是连通的,这又衍生出一个问题,使用并查集的时候,得需要节点的编号才可以,怎样确定节点的编号呢?可以采用trie树来确定节点的编号,cnt=1,按照颜色字符串输入的顺序,在trie树中建立一条路径,只要发现以前没有过该字符串,就让其id=cnt++,那么所输入的颜色节点的编号就变为了 1— cnt-1
对于第二个问题,用degree[]数组来保存每个顶点的度。无向图中,一个顶点的度就是有多少条边与其相连,所以在输入的时候,对于输入的两种颜色,对其编号进行degree[编号] ++就可以了。上面所说的奇度顶点(欧拉通路的两个端点),欧拉通路的两个端点有两种情况,一是颜色相同,那么在我们所建立的图上这两个端点是重合的,也就是奇度顶点的个数为0,另一种情况,颜色不同,那么奇度顶点就为2了,所以我们在这里要判断的是奇度顶点是否等于0或者等于2.
PS:做这道题真的学到好多东西。
参考:
http://blog.csdn.net/niushuai666/article/details/6549182
http://blog.csdn.net/lyy289065406/article/details/6647445
代码:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> using namespace std; const int maxn=250000; int degree[maxn*2+1];//每个顶点的度 int parent[maxn*2+1];//根节点是谁 int cnt=1;//顶点的个数,一根棍子有两个顶点 struct Trie { bool ok; int id; Trie *next[27]; Trie() { ok=0; for(int i=0;i<=27;i++) next[i]=NULL; } }root; int hash(char *s) { int len=strlen(s); Trie *p=&root; for(int i=0;i<len;i++) { int id=s[i]-'a'; if(!p->next[id]) p->next[id]=new Trie; p=p->next[id]; } if(p->ok) return p->id; else { p->ok=1; p->id=cnt++; } return p->id; } void init() { for(int i=1;i<=500000;i++) parent[i]=i; } int find(int x) { return parent[x]==x?x:find(parent[x]); } void unite(int x,int y) { x=find(x); y=find(y); if(x==y) return ; parent[x]=y; } int main() { char s1[11],s2[11]; memset(degree,0,sizeof(degree)); init(); while(scanf("%s%s",s1,s2)!=EOF) { int x=hash(s1); int y=hash(s2); degree[x]++,degree[y]++; unite(x,y); } cnt--; int self=0;//根节点为本身的个数 int oddNum=0;//度为奇数的顶点的个数 for(int i=1;i<=cnt;i++) { if(degree[i]%2) oddNum++; if(find(i)==i) self++; if(oddNum==3)//度数为奇数的定点个数>2 { cout<<"Impossible"<<endl; return 0; } if(self==2)//不连通 { cout<<"Impossible"<<endl; return 0; } } if(oddNum==0||oddNum==2) cout<<"Possible"<<endl; return 0; }
[ACM] POJ 2513 Colored Sticks (Trie树,欧拉通路,并查集),布布扣,bubuko.com
[ACM] POJ 2513 Colored Sticks (Trie树,欧拉通路,并查集)
标签:des style blog http color 使用
原文地址:http://blog.csdn.net/sr_19930829/article/details/37931437