NWERC 2012 Problem I Idol

又是个2-sat的模板题;

反正评委的选择必须有一个是正确的,1错误,那么2就必须正确;

这就是一个2-sat问题。

直接上白书的模板啊,不过稍微要注意的一点是对于第一个点必须要选择,不然就违反了题意;

代码:

 1 #include<cstdio>
 2 #define maxn 2005
 3 #define maxm 4005
 4 #include<vector>
 5 #include<cstring>
 6 using namespace std;
 7 struct twosat
 8 {
 9     int n;
10     vector<int>g[maxn*2];
11     bool mark[maxn*2];
12     int s[maxn*2],c;
13 
14     bool dfs(int x)
15     {
16         if(mark[x^1])return 0;
17         if(mark[x])return 1;
18         mark[x]=1;
19         s[c++]=x;
20         for(int i=0; i<g[x].size(); i++)
21             if(!dfs(g[x][i]))return 0;
22         return 1;
23     }
24     void init(int n)
25     {
26         this->n=n;
27         for(int i=0; i<2*n; i++)g[i].clear();
28         memset(mark,0,sizeof mark);
29     }
30     void add_clase(int x,int y)
31     {
32         g[x].push_back(y);
33     }
34     bool solve()
35     {
36         mark[1]=1,mark[0]=0;//强制让1选上去;
37         for(int i=2; i<n*2; i+=2)
38             if(!mark[i]&&!mark[i+1])
39             {
40                 c=0;
41                 if(!dfs(i))
42                 {
43                     while(c>0)mark[s[--c]]=0;
44                     if(!dfs(i+1))return 0;
45                 }
46             }
47             return 1;
48         }
49 } getans;
50 
51 int main()
52 {
53     int n,m,u,v;
54     while(scanf("%d%d",&n,&m)!=EOF)
55     {
56         getans.init(n);
57         for(int i=0; i<m; i++)
58         {
59             scanf("%d%d",&u,&v);
60             if (u<0) {u++;u=(-u)<<1;}
61             else {u--;u=u<<1|1;}
62             if (v<0) {v++;v=(-v)<<1;}
63             else {v--;v=v<<1|1;}
64             getans.add_clase(u^1,v);
65             getans.add_clase(v^1,u);
66         }
67         if(getans.solve())puts("yes");
68         else puts("no");
69     }
70     return 0;
71 }
View Code

 

posted @ 2013-10-05 19:38  Yours1103  阅读(198)  评论(0编辑  收藏  举报