• 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. ");
           else {
            for (int i=0;i<n;i++){
                if(mark[i*2]) printf("C ");
                //printf("%d ",mark[i]);
                else if(is_young(i)) printf("B ");
                else printf("A ");
            }
           }
        }
    return 0;
    }

  • 相关阅读:
    Exchanger
    信号量Semaphore
    CountDownLatch
    Condition
    WCF接口实例介绍
    时间显示
    pymysql-execute
    python之迭代器与生成器
    python之装饰器
    python之函数
  • 原文地址:https://www.cnblogs.com/lmjer/p/8312672.html
Copyright © 2020-2023  润新知