版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pengwill97/article/details/82083324
题意
一国有n个党派。每一个党派在议会中都有2个代表,现要组建和平委员会,要从每一个党派在议会的代表中选出1人,一共n人组成和平委员会。已知有一些代表之间存在仇恨,也就是说他们不能同一时候被选为和平委员会的成员,现要你推断满足要求的和平委员会是否能创立?假设能,请给出字典序最小的方案。
题解
输出字典序最小的,按照白书上的套路来就行了。
这题无限wa,原因是因为在寻找解的时候,每次找要先把保存节点的栈清空掉,否则会WA。
代码
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
const int nmax = 1e6+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const ull p = 67;
const ull MOD = 1610612741;
int head[nmax], tot;
struct edge {
int to, nxt;
} e[nmax<<1];
int dfn[nmax], low[nmax], ss[nmax], color[nmax], scc , st, dfs_clock, ban[nmax];
bool instack[nmax], isok;
stack<int> s;
void add_edge(int u, int v) {
e[tot].to = v;
e[tot].nxt = head[u];
head[u] = tot++;
}
void init() {
memset(head, -1, sizeof head);
memset(dfn ,0, sizeof dfn);
memset(low, 0, sizeof low);
memset(color, 0, sizeof color);
memset(ban, 0, sizeof ban);
scc = dfs_clock = st = tot = 0;
}
void tarjan(int u) {
dfn[u] = low[u] = ++dfs_clock;
ss[st++] = u;
instack[u] = true;
for(int i = head[u]; i != -1; i = e[i].nxt) {
int v = e[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(instack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]) {
scc ++;
int tmp;
for(;;) {
tmp = ss[--st];
instack[tmp] = false;
color[tmp] = scc;
if(tmp == u)
break;
}
}
}
bool dfs(int u) {
if(ban[u] == 2) return false;
if(ban[u] == 1) return true;
if(ban[u ^ 1] == 1) return false;
if(ban[u ^ 1] == 1) return true;
ban[u] = 1;
ban[u ^ 1] = 2;
s.push(u);
for(int i = head[u] ; i != -1; i = e[i].nxt) {
int v = e[i].to;
if(dfs(v) == false)
return false;
}
return true;
}
int n, m;
int main() {
while(scanf("%d %d" , &n, &m) != EOF) {
init();
for(int i = 1; i <= m; ++i) {
int u, v;
scanf("%d %d", &u, &v);
u--;
v--;
add_edge(u, v ^ 1);
add_edge(v, u ^ 1);
}
for(int i = 0; i < 2 * n; ++i) {
if(!dfn[i])
tarjan(i);
}
bool isok = true;
for(int i = 0; i < 2 * n; i += 2) {
if(color[i] == color[i ^ 1]) {
isok = false;
break;
}
}
if(!isok) {
printf("NIE\n");
continue;
} else {
isok = true;
for(int i = 0; i < 2 * n; i += 2) {
if(!ban[i] && !ban[i ^ 1]) {
while(!s.empty()) s.pop();
if(dfs(i) == false) {
while(!s.empty()) {
int now = s.top();
s.pop();
ban[now] = ban[now ^ 1] = 0;
}
dfs(i ^ 1);
}
}
}
for(int i = 0; i < 2 * n; i += 2) {
if(ban[i] == 1)
printf("%d\n",i + 1);
else
printf("%d\n",(i^1) + 1);
}
}
}
return 0;
}