将两种的种类并查集转化为普通并查集
例题: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.");
}
}
}
}
}
}

本文介绍了一种将涉及两种关系的并查集问题转化为普通并查集问题的方法,并通过两个实例详细展示了具体实现过程。
1459

被折叠的 条评论
为什么被折叠?



