• CROCMBTU 2012, Elimination Round (ACMICPC) D. Restoring Table 夜


    http://codeforces.com/contest/245/problem/D

    和今年长春赛区的 第二题一样 2-sat  将每一个数的每一位作为一个点  要么是 1 要么是 0

    2-sat 主要是代码长 比较繁琐 尤其是需要求结果的题目

    -----------不对劲呀 走在路上一想  这个题不用2—sat 就可以呀  晕 想多了 附加简单代码

    代码1:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    #include<stack>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const int INF=0x3f3f3f3f;
    const int N=102*31*2;
    int head[N],I;
    struct node
    {
        int j,next;
    }side[N*N/4];
    int low[N],dfn[N],f[N],deep;
    bool in[N],visited[N];
    stack<int>st;
    queue<int>qt;
    vector<int>tree[N];
    int sum[N];
    int color[N];
    int a[103],b[103][103];
    void add(int i,int j)
    {
        side[I].j=j;
        side[I].next=head[i];
        head[i]=I++;
    }
    void Tarjan(int x)
    {
        visited[x]=true;
        in[x]=true;
        st.push(x);
        low[x]=dfn[x]=deep++;
        for(int t=head[x];t!=-1;t=side[t].next)
        {
            int j=side[t].j;
            if(!visited[j])
            {
                Tarjan(j);
                low[x]=min(low[x],low[j]);
            }else if(in[j])
            {
                low[x]=min(low[x],dfn[j]);
            }
        }
        if(low[x]==dfn[x])
        {
            while(st.top()!=x)
            {
                in[st.top()]=false;
                f[st.top()]=x;
                st.pop();
            }
            in[st.top()]=false;
            f[st.top()]=x;
            st.pop();
        }
    }
    void buildtree(int m)
    {
        for(int i=0;i<2*m;++i)
        tree[i].clear();
        memset(sum,0,sizeof(sum));
        for(int i=0;i<2*m;++i)
        if(f[i]==i)
        {
            for(int t=head[i];t!=-1;t=side[t].next)
            {
                int j=side[t].j;
                if(f[j]==j)
                {
                    tree[j].push_back(i);
                    ++sum[i];
                }
            }
        }
    }
    void decside(int x)
    {
        for(unsigned int i=0;i<tree[x].size();++i)
        {
            --sum[tree[x][i]];
            if(sum[tree[x][i]]==0)
            {
                qt.push(tree[x][i]);
            }
        }
    }
    void topo(int m)
    {
        memset(color,0,sizeof(color));
        for(int i=0;i<2*m;++i)
        {
            if(sum[i]==0)
            qt.push(i);
        }
        while(!qt.empty())
        {
            int x=qt.front();qt.pop();
            if(color[x]!=0)
            continue;
            color[x]=1;
            int y=(x<m)?x+m:x-m;
            color[y]=-1;
            decside(x);
            decside(y);
        }
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n;
        while(cin>>n)
        {
           for(int i=1;i<=n;++i)
           for(int j=1;j<=n;++j)
           cin>>b[i][j];
           if(n==1)
           {cout<<"0"<<endl;continue;}
           int m=n*31;
           memset(head,-1,sizeof(head));
           I=0;
           for(int i=1;i<=n;++i)
           {
               for(int j=i+1;j<=n;++j)
               {
                   for(int x=0;x<31;++x)
                   {
                       int l=(i-1)*31+x;
                       int r=(j-1)*31+x;
                       if(b[i][j]&(1<<x))
                       {
                           add(l+m,l);
                           add(r+m,r);
                       }else
                       {
                           add(l,r+m);
                           add(r,l+m);
                       }
                   }
               }
           }
            memset(visited,false,sizeof(visited));
            memset(in,false,sizeof(in));
            deep=0;
            for(int i=0;i<2*m;++i)
            {
                if(!visited[i])
                Tarjan(i);
            }
            buildtree(m);
            topo(m);
            memset(a,0,sizeof(a));
            for(int i=0;i<m;i=i+31)
            {
                for(int j=0;j<31;++j)
                {
                    if(color[f[i+j]]==1)
                    a[i/31+1]=(a[i/31+1]|(1<<j));
                }
            }
    
            for(int i=1;i<=n;++i)
            {
                if(i>1)
                cout<<" ";
                cout<<a[i];
            }
            cout<<endl;
        }
        return 0;
    }
    

    代码2:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<queue>
    #include<stack>
    #include <iomanip>
    using namespace std;
    #define LL long long
    const int INF=0x3f3f3f3f;
    const int N=105;
    int a[N],b[N][N];
    int main()
    {
        //freopen("data.in","r",stdin);
        int n;
        while(cin>>n)
        {
           memset(a,0,sizeof(0));
           for(int i=1;i<=n;++i)
           for(int j=1;j<=n;++j)
           {
               cin>>b[i][j];
               if(i==j)
               continue;
               for(int l=0;l<31;++l)
               {
                   if(b[i][j]&(1<<l))
                   {
                       a[i]=a[i]|(1<<l);
                       a[j]=a[j]|(1<<l);
                   }
               }
           }
           for(int i=1;i<=n;++i)
           {
               if(i>1)
               cout<<" ";
               cout<<a[i];
           }
           cout<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    0317复利计算的回顾与总结
    0518 Scrum 项目 5.0
    0517 Scrum 项目4.0
    0512 Scrum 项目3.0
    实验三 进程调度模拟程序
    0505 Scrum 项目1.0
    0502团队项目 SCRUM团队成立
    0428 团队项目2.0
    0422团队项目
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/liulangye/p/2779637.html
Copyright © 2020-2023  润新知