SRM 452 Div2 1000pts

这题不难,求哈密顿路的,就是多了一个限制条件。

主要是合并满足给定路径的哈密顿路时要进行合并,可以用并查集的来做,我是直接用哈希表来做的,求出满足条件一共有几组的聚集后,其实就是求这些聚集的一个全排列,只不过聚集本身有可以变换为两种情况,不管怎样,这在高中排列组合中学过,还是很简单的。

另外,由于Java中提供了大数,因此可以用大数做比较大的那种运算,如求50的全排列。

~~.
import java.util.*;
import java.util.regex.*;
import java.math.*;

public class HamiltonPath {
   public int countPaths(String[] roads) {
		int ans=0;
		int n=roads.length;
		char[][] matrix=new char[n][n];
		Vector<HashSet<String>> vec=new Vector<HashSet<String>>();
		for(int i=0;i<n;i++){
			matrix[i]=roads[i].toCharArray();
		}
		
		for(int i=0;i<n;i++){
			int iflag=0;
			for(int j=0;j<n;j++){
				if(matrix[i][j]=='Y')
					iflag++;
			}
			if(iflag>2)
				return 0;
		}
		
		for(int i=0;i<n;i++){
			for(int j=i+1;j<n;j++){
				if(matrix[i][j]=='Y'){
					Vector<HashSet<String>> ll=new Vector<HashSet<String>>();
					boolean isIn=false;
					for(HashSet<String> hs:vec){//loop 1
						if(hs.contains(i+"")){
							if(hs.contains(j+""))
								return 0;
							else{
								ll.add(hs);
								hs.add(j+"");
								isIn=true;
							}
						}else if(hs.contains(j+"")){
							if(hs.contains(i+""))
								return 0;
							else{
								ll.add(hs);
								hs.add(i+"");
								isIn=true;	
							}
						}
					}//loop 1 over
					merge(ll,vec);
					if(!isIn){
						HashSet<String> hs=new HashSet<String>();
						hs.add(i+"");
						hs.add(j+"");	
						vec.add(hs);
					}	
				}//if
			}//inner for loop		
		}//outter for loop
		
		int temp=0;
		for(HashSet<String> hs:vec){
			temp+=hs.size();
		}
		int n1=n-temp;
		int n2=vec.size();
		
		BigInteger big=getAllPos(n1+n2);
		long pow=get2Pow(n2);
		big=big.multiply(new BigInteger(pow+""));
		ans=big.mod(new BigInteger(""+1000000007)).intValue();
		
		return  ans;
   }
   
   BigInteger getAllPos(int n){
   	BigInteger ans=BigInteger.ONE;
   	for(int i=1;i<=n;i++)
   		ans=ans.multiply(new BigInteger(i+""));
   		
   	return ans;	
   }
   
   void merge(Vector<HashSet<String>> ll,Vector<HashSet<String>> vec){
   	if(ll.size()>1){
   		HashSet<String> init=ll.get(0);
   		for(int i=1;i<ll.size();i++){
   			Iterator<String> itor=ll.get(i).iterator();
   			while(itor.hasNext())
   				init.add(itor.next());
   		}
   		
   		for(int i=1;i<ll.size();i++){
   			vec.remove(ll.get(i));
   		}
   	}
   }
   
   long get2Pow(int n){
   	long ans=1;
   	while(n-->0){
   		ans*=2;	
   	}	
   	return ans;
   }
}

你可能感兴趣的:(J#)