CROC-MBTU 2012, Elimination Round (ACM-ICPC) 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;

}

 

你可能感兴趣的:(table)