题目链接:Xor the graph
对于每条边,如果左右相等那么就是一个选,一个不选的问题了。
然后2-SAT搞一搞就行了,然后x随机输出一个正确率都挺大的。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=6e5+10;
mt19937 rnd(time(0));
int n,m,a[N],dfn[N],low[N],scc[N],vis[N],co,cnt;
vector<int> g[N]; stack<int> s;
inline void add(int a,int b){g[a].push_back(b);}
void Tarjan(int x){
dfn[x]=low[x]=++cnt; s.push(x),vis[x]=1;
for(auto to:g[x]){
if(!dfn[to]) Tarjan(to),low[x]=min(low[x],low[to]);
else if(vis[to]) low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x]){
int u; co++;
do{
u=s.top(); s.pop(); vis[u]=0; scc[u]=co;
}while(u!=x);
}
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1,x,y;i<=m;i++){
scanf("%d %d",&x,&y); if(a[x]!=a[y]) continue;
add(x,y+n),add(x+n,y),add(y,x+n),add(y+n,x);
}
for(int i=1;i<=n*2;i++) if(!dfn[i]) Tarjan(i);
for(int i=1;i<=n;i++) if(scc[i]==scc[i+n]) return puts("-1"),0;
vector<int> v;
for(int i=1;i<=n;i++) if(scc[i]>scc[i+n]) v.push_back(i);
printf("%d %d\n",v.size(),rnd()%(991242)+133);
for(auto i:v) printf("%d ",i);
return 0;
}