POJ3678【错误总会让自己有收获的】

   首先我是的确确定了LRJ那个代码也是判断一个点的两种状态是否在一个连通分量内。

 

   关于自己做的,自己又确定了一些,让自己那样先,比如说对于 3 6 1 AND这样3 6都已经确定的点,自己用Num记录的话结果死的很惨。

 

   我也确定下,现场比赛自己创算法(指的是代码比较新)的话也许会死的很惨。。。

  

   2-SAT,后来我忽然想到就是确定的位置也可以用这种对称方法做出来,就加一个每种状态都可以推出这种状态呗。。

 

   顺便知道了RANK上排名超前的一般都加入了输入输出加速了

 

   还顺便知道了OJ上的数据也许是随机出的

 

   还顺便学习了下tarjan的2-SAT做法,其实思想本来就是类似的。

 

 

#include <iostream>

#include <cstdio>

#include <cstring>

#include <vector>

using namespace std;



//我的错误就是无法判断已经确定结果的边然后。。。。

const int maxn = 1500;

int n,m;

vector<int> G[maxn*3];

bool mark[maxn*3];

int s[maxn*3],c;

char op[10];



bool dfs(int x)

{

    if(mark[x^1]) return false;//这个一定是强连通分量果然

    if(mark[x]) return true;

    mark[x]=true;

    s[c++]=x;

    for(int i=0;i<G[x].size();i++)

        if(!dfs(G[x][i])) return false;

    return true;

}



void init()

{

    for(int i=0;i<n*2;i++)  G[i].clear();

    memset(mark,0,sizeof(mark));

}



bool solve()

{

    for(int i = 0;i < n*2; i += 2)

    {

      if( !mark[i] && !mark[i+1] )

      {

          c = 0;

          if( !dfs(i) )

          {

              while(c>0)

                mark[s[--c]]=false;

              if(!dfs(i+1)) return false;

          }

      }

    }

    return true;

}



int main()

{

    int a,b,c;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        init();

        for(int i=0;i<m;i++)

        {

            scanf("%d%d%d%s",&a,&b,&c,op);

                if(!strcmp(op,"AND"))

                {

                    if(c==1)

                    {

                        G[a*2].push_back(b*2);//如果出现这种情况那么一定是真。就这样。

                        G[a*2+1].push_back(b*2);



                        G[b*2].push_back(a*2);

                        G[b*2+1].push_back(a*2);

                    }

                    else if(c==0)

                    {

                        G[a*2].push_back(b*2+1);//真只能放假

                        G[b*2].push_back(a*2+1);

                    }

                }

                //////////

               else if(!strcmp(op,"OR"))

                {

                    if(c==1)

                    {

                       G[a*2+1].push_back(b*2);//a假b必须为真

                       G[b*2+1].push_back(a*2);

                    }

                    else if(c==0)

                    {

                       G[a*2].push_back(b*2+1);

                       G[a*2+1].push_back(b*2+1);//必须都为0



                       G[b*2].push_back(a*2+1);

                       G[b*2+1].push_back(a*2+1);

                    }

                }

               ////////////

              else if(!strcmp("XOR",op))

                {

                    if(c==1)

                    {

                             G[a*2+1].push_back(b*2);

                             G[a*2].push_back(b*2+1);



                             G[b*2+1].push_back(a*2);

                             G[b*2].push_back(a*2+1);

                    }

                    else if(c==0)

                    {

                             G[a*2+1].push_back(b*2+1);

                             G[a*2].push_back(b*2);



                             G[b*2+1].push_back(a*2+1);

                             G[b*2].push_back(a*2);

                    }

               }

        }



        if(solve()==false) printf("NO\n");

        else

        {

            printf("YES\n");

        }

    }

    return 0;

}


 

 

你可能感兴趣的:(poj)