UVA live3713

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;
}

posted @ 2018-01-18 19:26  lmjer  阅读(121)  评论(0编辑  收藏  举报