P5782 [POI2001]和平委员会
作者:互联网
基于并查集的缩点 \(Dfs\)
标题党,jbl
这个裸的 \(2-Sat\) 就不用说了吧,这里只讲思路
读完题目,定义 \(x\) 与 \(x^{'}\) 一组,我们对于每一条规定转化一下,其实就是:
\(a\) 必须与 \(b^{'}\) 一组,\(b\) 必须与\(a^{'}\)一组,\(rule_1\)
依照 \(rule_1\) 进行建图,思考建完图后,我们如何得到正解。
首先一个显而易见的是:如果同一组的 \(2\) 个点都在同一强连通分量内,那么肯定无解,因为一旦选了强连通分量内的一点,那么整个强连通分量的点都要被选,这与题目中每个党派都在委员会中恰有 \(1\) 个代表矛盾,\(rule_2\)。
再回过头来,发现缩完点后我们的图是个 \(DAG\),想到拓扑排序。
如果对于同一组的两个点 \(x\) 与 \(x^{'}\),我们定义 \(rule_3\):优先选择拓扑序后的结点。为什么呢?
其实原因很简单,因为这是 \(DAG\),而拓扑排序越早记录到的结点,就越容易影响到后面的结点,简单来说,就是有后效性。
最后再来讲一下标题。因为题解区好像都是tarjan?
其实就是暴力\(Dfs\)啦。
记 \(dep[i]\) 为 \(Dfs\) 中搜索到的序号,那么有以下代码:
void dfs(int pos){
for(int i=h[pos]; i; i=edge[i].nxt){
int to=edge[i].to;
if(!dep[to]){\\1
dep[to]=dep[pos]+1;
dfs(to);
}
if(dep[find(to)]>0){\\2
if(dep[find(pos)]<dep[f[to]])
f[f[to]]=f[pos];
else f[f[pos]]=f[to];
}
}
dep[pos]=-1, top_mark[pos]=++cnt;\\3
}
一步一步讲:
-
没走到的点,走下去。
-
如果我所到的点,仍在递归栈中(就是走出了一个环),那么将这个点的集合并入并查集中。
-
修改 \(dep\),使得下一次搜索无法搜到。
Code:
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define N 80000
#define M 20000
using namespace std;
int f[N*2+5];
int find(int x){
if(f[x]==x) return x;
return f[x]=find(f[x]);
}
struct Edge{
int to, nxt;
}edge[2*M+5];
int tot, h[N+5];
void add(int a, int b){
edge[++tot].to=b, edge[tot].nxt=h[a];
h[a]=tot;
}
int n, m, cnt;
int dep[N+5], top_mark[N+5];
void dfs(int pos){
for(int i=h[pos]; i; i=edge[i].nxt){
int to=edge[i].to;
if(!dep[to]){
dep[to]=dep[pos]+1;
dfs(to);
}
if(dep[find(to)]>0){
if(dep[find(pos)]<dep[f[to]])
f[f[to]]=f[pos];
else f[f[pos]]=f[to];
}
}
dep[pos]=-1, top_mark[pos]=++cnt;//记拓扑序
}
int main(){
int a, b;
scanf("%d%d", &n, &m);
for(int i=1; i<=2*n; i++) f[i]=i;
for(int i=1; i<=m; i++){
scanf("%d%d", &a, &b);
int a_=a%2?a+1:a-1, b_=b%2?b+1:b-1;
add(a, b_), add(b, a_);
}
for(int i=1; i<=n*2; i++)
if(!dep[i]) dfs(dep[i]=i);
for(int i=1; i<=n*2; i+=2)
if(find(i)==find(i+1)) return printf("NIE")*0;
for(int i=1; i<=n*2; i+=2){
int i_=i+1;
if(top_mark[find(i)]<top_mark[find(i_)])
printf("%d\n", i);
else printf("%d\n", i_);
}
return 0;
}
\(over\)
标签:P5782,int,POI2001,pos,tot,dep,edge,和平,find 来源: https://www.cnblogs.com/sizeof127/p/14614505.html