洛谷 P5782 [POI2001]和平委员会
作者:互联网
B 国有 \(n\) 个党派,每个党派有 \(2\) 名代表。有的代表互相讨厌。现创立一个和平委员会,要求每个党派恰好有 \(1\) 名代表在委员会内,且所有委员都不讨厌其他委员。
2-SAT 裸题。
#include <cstdio>
#include <algorithm>
const int MAXN = 1.6e4 + 19, MAXM = 2e4 + 19;
struct Edge{
int to, next;
}edge[MAXM << 2];
int cnt, head[MAXN << 1];
inline void add(int from, int to){
edge[++cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt;
}
int ind;
int stack[MAXN << 1], top, vist[MAXN << 1];
int dfn[MAXN << 1], low[MAXN << 1];
int color[MAXN << 1], color_cnt;
void dfs(int node){
dfn[node] = low[node] = ++ind;
stack[++top] = node, vist[node] = true;
for(int i = head[node]; i; i = edge[i].next)
if(!dfn[edge[i].to]){
dfs(edge[i].to);
low[node] = std::min(low[node], low[edge[i].to]);
}
else if(vist[edge[i].to])
low[node] = std::min(low[node], low[edge[i].to]);
if(dfn[node] == low[node]){
++color_cnt;
while(stack[top + 1] != node){
color[stack[top]] = color_cnt;
vist[stack[top]] = false;
--top;
}
}
}
int n, m;
int main(){
std::scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i){
add(i * 2 - 1 + n * 2, i * 2);
add(i * 2 + n * 2, i * 2 - 1);
add(i * 2 - 1, i * 2 + n * 2);
add(i * 2, i * 2 - 1 + n * 2);
}
for(int a, b, i = 1; i <= m; ++i){
std::scanf("%d%d", &a, &b);
add(a, b + n * 2);
add(b, a + n * 2);
}
for(int i = 1; i <= n * 4; ++i)
if(!dfn[i])
dfs(i);
for(int i = 1; i <= n * 2; ++i)
if(color[i] == color[i + n * 2])
return std::puts("NIE"), 0;
for(int i = 1; i <= n * 2; ++i)
if(color[i] < color[i + n * 2])
std::printf("%d\n", i);
return 0;
}
标签:洛谷,P5782,int,POI2001,19,党派,委员会,MAXM,include 来源: https://www.cnblogs.com/natsuka/p/12815007.html