对着题解脑子都大了,看了一圈正解是 2-SAT 没脑子思考暂时,就写了一个暴力
水过了……不过这个暴力应该是有问题的
先写个错误的当记号(以后回来学)
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=40010;
vector<int>G[maxn];
int vis[maxn],n,cnt;
int S[maxn];
bool dfs(int now)
{
// printf("1.now =%d\n",now);
if (vis[now]==1) return true;
if (vis[now]==0) return false;
vis[now]=1; vis[now^1]=0;
// printf("2.now= %d\n ",now);
S[cnt++]=now;
for (int i=0;i<G[now].size();i++)
if (!dfs(G[now][i])) return false;
return true;
}
bool cz()
{
memset(vis,-1,sizeof(vis));
for (int i=0;i<n;i+=2)
if (vis[i]==-1 && vis[i^1]==-1)//前面构建的协会忽略了这个党派,进行重组,对栈清0考虑到for是顺序进行,这样不能保证前面的党派一定被选择,应该有问题?
{
cnt=0;
// printf("?=%d",i);
if (!dfs(i))//把自己的放进去的行为失败了,对栈清0
{
while (cnt){ vis[S[--cnt]]=-1; vis[S[cnt]^1]=-1; }
if (!dfs(i^1)) return false;
}
}
return true;
}
int main()
{
//attention!最初的n为党派数量,表示人的时候要*2;
//一个协会需要每个党派都有一个人在,问是否存在这样的协会
//一个党派有两个候选人,他们互相是竞争关系,有你没我,有我没他
//不同党派中的人有私人感情仇视,要分离他们,打造一个和谐的协会
//关于^ 奇数-1 偶数+1 也就是说 0 1 || 2 3|| 被这样分组,所以对每个数-1,更容易进行分组
//放的G表示不是不喜欢看到的人------>按照题意,不喜欢的会被输入,但是不同的党派又必须有人,所以刨去不喜欢的就是不是不喜欢的必须存在的,需要判断必须存在的人是否存在
//dfs 判断这个人 在协会里 true 不在协会里 false
//如果他和他的竞争对手 都不在 把自己放进去
//vis 表示1 选中 0 未选中 -1这个党派未被选择
int m,i,u,v;
while (~scanf("%d%d",&n,&m))
{
n=n*2;
for (i=0;i<n;i++) G[i].clear();
cnt=0;
while (m--)
{
scanf("%d%d",&u,&v);
u--; v--;
G[u].push_back(v^1);
G[v].push_back(u^1);
}
if (cz())
{
for (i=0;i<n;i++)
if (vis[i]==1) printf("%d\n",i+1);
}
else printf("NIE\n");
}
return 0;
}