因为要求输出字典序最小的解,所以用暴力染色
具体有点像二分图染色
遍历0-2*n-1个点,尝试将每个点染成1,该点所能到达的所有点都要染成1
如果不行,则把上该点的影响消除,再把对立点染成1,如果还不行就无解
#include<bits/stdc++.h> #include<vector> using namespace std; #define maxn 200005 vector<int>G[maxn]; int n,m,stk[maxn],top,mark[maxn]; bool dfs(int x){ if(mark[x^1])return false; if(mark[x])return true; mark[x]=true; stk[top++]=x; for(int i=0;i<G[x].size();i++) if(!dfs(G[x][i]))return false; return true; } bool work(){ for(int i=0;i<2*n;i+=2) if(!mark[i] && !mark[i+1]){ top=0; if(!dfs(i)){//如果给i染色为1不成立 while(top)//把栈里的染色清空 mark[stk[--top]]=0; if(!dfs(i+1))return false; } } return 1; } int main(){ while(cin>>n>>m){ for(int i=0;i<maxn;i++) G[i].clear(); int x,y; for(int i=0;i<m;i++){ cin>>x>>y;--x;--y; G[x].push_back(y^1); G[y].push_back(x^1); } memset(mark,0,sizeof mark); top=0; if(!work())puts("NIE"); else { for(int i=0;i<2*n;i++) if(mark[i])cout<<i+1<<endl; } } }