题意:有n对人,编号从1-2*n,有m对人互相不喜欢,每对人中必需选1个人加入和平委员会,求字典序最小的解
解析:直接2-sat建图然后用染色法跑dfs即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=8005*2;
vector<int> g[maxn];
bool v[maxn];
int st[maxn],top;
bool dfs(int u)
{
if(v[u^1]) return false;
if(v[u]) return true;
v[u]=true;
st[top++]=u;
for(int i=0;i<g[u].size();i++)
{
if(!dfs(g[u][i]))
return false;
}
return true;
}
bool twosat(int n)
{
memset(v,0,sizeof v);
for(int i=0;i<n;i+=2)
{
if(v[i]||v[i^1]) continue;
top=0;
if(!dfs(i))
{
while(top) v[st[--top]]=false;
if(!dfs(i^1))
return false;
}
}
}
int main()
{
ios_base::sync_with_stdio(0);
int n,m;
while(cin>>n>>m)
{
for(int i=0;i<2*n;i++)
g[i].clear();
int x,y;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
x--,y--;
g[x].push_back(y^1);
g[y].push_back(x^1);
}
if(twosat(2*n))
{
for(int i=0;i<2*n;i++)
if(v[i])
cout<<i+1<<endl;
}
else cout<<"NIE"<<endl;
}
return 0;
}