将两种的种类并查集转化为普通并查集
例题:poj 1703 和 hdu 1829
当有N各节点且他们之间只有两种关系时,可以再虚拟出N个节点,对这2*N个节点进行操作即可
//hdu1829 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; public class hdu1829ABugsLife { static int max=6010; static int parent[]=new int[max]; static StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); final static int nextInt() throws IOException { in.nextToken(); return (int) in.nval; } static void init() { for(int i=0;i<max;i++) parent[i]=i; } static int find(int x) { if(x!=parent[x]) parent[x]=find(parent[x]); return parent[x]; } static void union(int a,int b) { int fa=find(a); int fb=find(b); if(fa==fb) return; parent[fa]=fb; } public static void main(String[] args) throws IOException { int num=nextInt(); for(int i=1;i<=num;i++) { init(); int n=nextInt(); int m=nextInt(); int data1[]=new int[m+1]; int data2[]=new int[m+1]; for(int j=1;j<=m;j++) { data1[j]=nextInt(); data2[j]=nextInt(); } boolean mark=true; for(int j=1;j<=m;j++) { int a=data1[j]; int b=data2[j]; int fa=find(a); int fb=find(b); // System.out.println("fa :"+fa+"fb :"+fb); if(fa==fb) { System.out.println("Scenario #"+i+":"); System.out.println("Suspicious bugs found!"); mark=false; // System.out.println(mark); break; }else { union(a,b+n); union(b,a+n); // union(a,b); } } if(mark) { System.out.println("Scenario #"+i+":"); System.out.println("No suspicious bugs found!"); } System.out.println(); } } }
//poj1703/*将n个人的看作是有2*n个,若a与b不在同一个集合时,就将a与(b+n)合并,b与(a+n)合并 * 这样就转化为了普通并查集 */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; public class poj1703T { static StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); final static int nextInt() throws IOException { in.nextToken(); return (int) in.nval; } static String next() throws IOException { in.nextToken(); return (String)in.sval; } static int max=300010; static int parent[]=new int[max]; static void init() { for(int i=0;i<max;i++) parent[i]=i; } static int find(int x) { if(x!=parent[x]) { parent[x]=find(parent[x]); } return parent[x]; } static void union(int a,int b) { int fa=find(a); int fb=find(b); if(fa==fb) return; parent[fa]=fb; } public static void main(String[] args) throws IOException { // Scanner in=new Scanner(System.in); int num=nextInt(); while(num--!=0) { init(); int n=nextInt(); int m=nextInt(); for(int i=1;i<=m;i++) { String inc=next(); int a=nextInt(); int b=nextInt(); if(inc.equals("D")) { union(a,b+n); union(b,a+n); }else { if(find(a)==find(b)) System.out.println("In the same gang."); else if(find(a)==find(b+n)||find(b)==find(a+n)) { System.out.println("In different gangs."); }else { System.out.println("Not sure yet."); } } } } } }