又是个2-sat的模板题;
反正评委的选择必须有一个是正确的,1错误,那么2就必须正确;
这就是一个2-sat问题。
直接上白书的模板啊,不过稍微要注意的一点是对于第一个点必须要选择,不然就违反了题意;
代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }