You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?
Input
Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.
Output
If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.
Sample Input
blue red red violet cyan blue blue magenta magenta cyanSample Output
PossibleHint
Huge input,scanf is recommended.
分析:经典的欧拉回路问题。。。,每次只经过一条边且仅一次
具体见代码:
/* 欧拉回路:
* ①图是连通图
* ②只有偶数度顶点或者只有两个奇度顶点
* 这道题实质就是判断是否能构成一个欧拉回路
* 连通性可以通过并查集来判断
* 顶点度数的统计可以结合字典树来统计
* 使用字典树可以统计颜色的种类
* */
import java.util.*;
public class Main{
static Scanner in = new Scanner(System.in);
static int[] f = new int[500010];
static int[] degree = new int[500010];
//寻找根节点
static int find(int x){
if(f[x]==-1)
return x;
else
return f[x] = find(f[x]);
}
//合并集合
static void merge(int a,int b){
int t1 = find(a);
int t2 = find(b);
if(t1!=t2)
f[t1]=t2;//往右合并
}
public static void main(String args[]){
//初始化
Arrays.fill(f, -1);
Arrays.fill(degree, 0);
TrieNode root = new TrieNode();
int k = in.nextInt();
String s1;String s2;
int a,b;
while(k-->0) {
s1 = in.next();
s2 = in.next();
a = root.insert(root, s1);
b = root.insert(root, s2);
// System.out.println(a+" "+b);
//维护度数数组
degree[a]++;
degree[b]++;
merge(a, b);
}
int color = root.color;
int cnt1 =0 ,cnt2=0;
for (int i = 0; i < color; i++) {
if(f[i]==-1) cnt1++;//根节点数目
if(degree[i]%2==1) cnt2++;//奇数度顶点数目
if(cnt1>1) break;
if(cnt2>2) break;
}
//cnt1==0木棒的数目可能为零
if((cnt1==0||cnt1==1)&&(cnt2==0||cnt2==2))
System.out.println("Possible");
else
System.out.println("Impossible");
}
}
//字典树节点
class TrieNode{
static int size = 26;//字符的种类,即每个节点的孩子数目
static int color = 0;
int id;//每种颜色的ID
TrieNode[] son;
boolean isEnd;
TrieNode() {
id = 0;
son = new TrieNode[size];
isEnd = false;
}
int insert(TrieNode root,String str){
TrieNode p = root;//每次从根节点开始
int len=str.length();
for(int i=0; i<len; i++){
if(p.son[str.charAt(i)-'a']==null){
p.son[str.charAt(i)-'a']=new TrieNode();
}
p=p.son[str.charAt(i)-'a']; //字符串每个字符向下一层
}
//是否到了一个颜色的结束
if(p.isEnd){
return p.id;
}
else{
p.isEnd = true;
p.id = color++;
return p.id;
}
}
}
字典树存储效率比较高。。。。