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

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);
    }    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值