蓝桥侦探
蓝桥:https://www.lanqiao.cn/problems/1136/learning/
对应LeetCode:https://leetcode.cn/problems/possible-bipartition/
题目描述
小明是蓝桥王国的侦探。
这天,他接收到一个任务,任务的名字叫分辨是非,具体如下:
蓝桥皇宫的国宝被人偷了,犯罪嫌疑人锁定在 NN 个大臣之中,他们的编号分别为 1\sim N1∼N。
在案发时这 NN 个大臣要么在大厅11,要么在大厅22,但具体在哪个大厅他们也不记得了。
审讯完他们之后,小明把他们的提供的信息按顺序记了下来,一共 MM 条,形式如下:
x y
,表示大臣 xx 提供的信息,信息内容为:案发时他和大臣 yy 不在一个大厅。
小明喜欢按顺序读信息,他会根据信息内容尽可能对案发时大臣的位置进行编排。
他推理得出第一个与先前信息产生矛盾的信息提出者就是偷窃者,但推理的过程已经耗费了他全部的脑力,他筋疲力尽的睡了过去。作为他的侦探助手,请你帮助他找出偷窃者!
输入描述
第 11 行包含两个正整数 N,MN,M,分别表示大臣的数量和口供的数量。
之后的第 2 \sim M+12∼M+1 行每行输入两个整数 x , yx,y,表示口供的信息。
1\leq N,M \leq 5\times10^51≤N,M≤5×105,1 \leq x,y\leq N1≤x,y≤N。
输出描述
输出仅一行,包含一个正整数,表示偷窃者的编号。
输入输出样例
示例 1
输入
4 5
1 2
1 3
2 3
3 4
1 4
输出
2
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
题解
思路:反向点 + 并查集
图源:LeetCode【宫水三叶】判定二分图模板题的题解
代码
import java.util.Scanner;
import java.io.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int[] father;
public static void main(String[] args) throws IOException{
StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//在此输入您的代码...
sc.nextToken();
int N = (int) sc.nval;
sc.nextToken();
int M = (int) sc.nval;
//并查集
father = new int[2 * N +1];
//初始化
for(int i = 0; i <= 2*N; i++){
father[i] = i;
}
while(M-- > 0){
sc.nextToken();
int x = (int) sc.nval;
sc.nextToken();
int y = (int) sc.nval;
if(find(x) == find(y)){
System.out.println(x);
return;
}
union(x,y+N);
union(x+N,y);
}
}
//寻找根节点
public static int find(int i){
if(father[i] == i) return i;
father[i] = find(father[i]);
return father[i];
}
//合并集合
public static void union(int x, int y){
int fx = find(x);
int fy = find(y);
if(fx != fy) father[fx] = fy;
}
}