N根木棍,两头都有颜色,拼接的时候,必须将颜色一致的接在一起,问能否把全部木棍拼成一整根?
1.颜色映射到数字
map效率低,超时。因此用字典树。
2.判断能否形成通路
条件:所有点的度数都是偶数,或者只有两个点的度数是奇数
(dad是并查集的数组,判断是否全部连通)
for(int i=0;i<color;i++) {
if(dad[i]==-1) dadcnt++;
if(deg[i]%2!=0) degcnt++;
if(dadcnt>1) break;
if(degcnt>2) break;
}
if((degcnt==0||degcnt==2)&&(dadcnt==0||dadcnt==1)) {
System.out.println("Possible");
}
else
System.out.println("Impossible");
总结:了解了字典树的功能并不局限,复习了下并查集。
完整代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Node{
Node[] next=new Node[26];
int complete,num;
}
public class Main{
static BufferedReader sc=new BufferedReader(new InputStreamReader(System.in));
static int color=0;
static int [] deg=new int[500010];
static int [] dad=new int[500010];
static int insert(Node root,String s) {
for(int i=0;i<s.length();i++) {
if(root.next[s.charAt(i)-'a']==null) {
Node tmp=new Node();
root.next[s.charAt(i)-'a']=tmp;
}
root=root.next[s.charAt(i)-'a'];
}
if(root.complete==1) {
return root.num;
}
else {
root.complete=1;
root.num=color++;
return root.num;
}
}
static int find(int x) {
//查到该点的老大,返回
if(dad[x]==-1)
return x;
else
return dad[x]=find(dad[x]);
}
static void bind(int head,int rear) {
int a=find(head);
int b=find(rear);
//查到各自的老大,如果不同,就连接
if(a!=b)
dad[a]=b;
}
public static void main(String[] args) throws IOException {
String s;
Node root=new Node();
Arrays.fill(dad, -1);
while((s=sc.readLine())!=null) {
String [] str;
str=s.split(" ");
int head=insert(root,str[0]);
int rear=insert(root,str[1]);
//获得颜色的映射,此种颜色度数+1
deg[head]++;
deg[rear]++;
bind(head,rear);
}
int dadcnt=0,degcnt=0;
for(int i=0;i<color;i++) {
if(dad[i]==-1) dadcnt++;
if(deg[i]%2!=0) degcnt++;
if(dadcnt>1) break;
if(degcnt>2) break;
}
if((degcnt==0||degcnt==2)&&(dadcnt==0||dadcnt==1)) {
System.out.println("Possible");
}
else
System.out.println("Impossible");
System.exit(0);
}
}