2-sat 找好怎样连边即可
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1000000;
bool mark[maxn*2+10];
int age[maxn*2];
int m,n;
int s[maxn*2+10];
int top;
int tot=0;
struct my{
int v;
int next;
};
int fa;
my bian[maxn*2];
int adj[maxn];
void myinsert(int u,int v){
bian[++fa].v=v;
bian[fa].next=adj[u];
adj[u]=fa;
}
void init(){
memset(bian,-1,sizeof(bian));
memset(adj,-1,sizeof(adj));
fa=0;
tot=0;
memset(mark,false,sizeof(mark));
}
void addbian2(int u,int v){
myinsert(u*2+1,v*2);
myinsert(v*2+1,u*2);
}
void addbian1(int u,int v){
myinsert(u*2,v*2+1);
myinsert(v*2,u*2+1);
}
bool is_young(int u){
return age[u]*n<tot;
}
bool dfs(int x){
if(mark[x^1]) return false;
if(mark[x]) return true;
mark[x]=true;
s[top++]=x;
for (int i=adj[x];i!=-1;i=bian[i].next)
//int u=bian[i].v;
if(!dfs(bian[i].v)) return false;
return true;
}
bool two_sat(){
for (int i=0;i<n*2;i+=2){
if(!mark[i]&&!mark[i+1]){
top=0;
if(!dfs(i)){
while(top>0) mark[s[--top]]=false;
if(!dfs(i+1)) return false;
}
}
}
return true;
}
int main(){
int u,v;
while(scanf("%d%d",&n,&m)&&n!=0&&m!=0){
init();
for (int i=0;i<n;i++){
scanf("%d",&age[i]);
tot+=age[i];
}
for (int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
u--;
v--;
if(u==v) continue;
addbian1(u,v);
if(is_young(u)==is_young(v))
addbian2(u,v);
}
if(!two_sat()) printf("No solution.\n");
else {
for (int i=0;i<n;i++){
if(mark[i*2]) printf("C\n");
//printf("%d\n",mark[i]);
else if(is_young(i)) printf("B\n");
else printf("A\n");
}
}
}
return 0;
}