zoukankan      html  css  js  c++  java
  • UVALive 4452 The Ministers' Major Mess(2-sat)

    2-sat。又学到了一种使用的方法:当确定选择某中状态A时,从它的对立状态A^1引一条边add(A^1,A),从而使凡是dfs经过对立状态,必然return false;即保证若存在一种可能性,必然是经过该状态A的。

    题意:m个人对n个方案投票,每人之多投4票,是否存在一种方案使每个人所投的一半以上的票被采纳。依次输出每个议题最终的结果。

    1、注意是一半以上,我一开始理解成一半,结果无法根据必然性建边。<=2票则都被采纳,<=4票则至多有一票不被采纳。

    2、输出时要注意,因为每个议题的结果都不一定相同,所以需要一一判断。需要分别进行solve(i),和solve(i+1)。这里一开始我直接是把solve()函数中的dfs(i)和dfs(i+1)分开,wa了,后来考虑发现,solve()一次,是对遍历整个方案寻找可行性;而dfs()只是对一个连通的量做了标记。

    注意:分别检查同一个议题的两种状态,确定从状态A经过,add(A^1,A),结束要记得G[i].pop_back();

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<vector>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int MAXN=555;
      8 
      9 struct Vote{
     10     int v,c;
     11 }vote[MAXN][5];
     12 
     13 bool mark[MAXN<<1];
     14 int res[MAXN];
     15 int s[MAXN<<1],c;
     16 vector<int >G[MAXN<<1];
     17 
     18 void init(int n)
     19 {
     20     for(int i=0;i<(n<<1);i++)
     21         G[i].clear();
     22     memset(mark,0,sizeof(mark));
     23 }
     24 
     25 void add(int x,int dx,int y,int dy)
     26 {
     27     x=(x<<1)+dx;
     28     y=(y<<1)+dy;
     29     G[x].push_back(y);
     30 }
     31 
     32 bool dfs(int x)
     33 {
     34     if(mark[x^1])
     35         return false;
     36     if(mark[x])
     37         return true;
     38     s[c++]=x;
     39     mark[x]=true;
     40     for(int i=0;i<G[x].size();i++)
     41         if(!dfs(G[x][i]))
     42             return false;
     43     return true;
     44 }
     45 
     46 bool solve(int n)
     47 {
     48     for(int i=0;i<(n<<1);i+=2)
     49     {
     50         if(!mark[i]&&!mark[i+1]){
     51             c=0;
     52             if(!dfs(i)){
     53                 while(c>0)
     54                     mark[s[--c]]=false;
     55                 if(!dfs(i+1))
     56                     return false;
     57             }
     58         }
     59     }
     60     return true;
     61 }
     62 
     63 bool test(int n)
     64 {
     65     for(int i=0;i<n;i++)
     66     {
     67         int ans=0;
     68         memset(mark,0,sizeof(mark));
     69         add(i,1,i,0);
     70         while(c>0)
     71             mark[s[--c]]=false;
     72         if(solve(n))
     73             ans+=1;
     74         G[(i<<1)+1].pop_back();
     75         
     76         memset(mark,0,sizeof(mark));
     77         add(i,0,i,1);
     78         while(c>0)
     79             mark[s[--c]]=false;
     80         if(solve(n))
     81             ans+=2;
     82         G[i*2].pop_back();
     83 
     84         if(ans==0)
     85             return false;
     86         else if(ans==1)
     87             res[i]=-1;
     88         else if(ans==2)
     89             res[i]=1;
     90         else if(ans==3)
     91             res[i]=0;
     92     }
     93     return true;
     94 }
     95 
     96 int main()
     97 {
     98     int n,m;
     99     int cnt=0,ans;
    100     while(~scanf("%d%d",&n,&m))
    101     {
    102         if(!n&&!m)
    103             return 0;
    104 
    105         init(n);         //!!
    106         for(int i=0;i<m;i++)
    107         {
    108             scanf("%d",&ans);
    109 
    110             for(int j=0;j<ans;j++)
    111             {
    112                 int x;
    113                 char ch[2];
    114                 scanf("%d %s",&x,ch);
    115                 vote[i][j].v=--x;
    116                 if(ch[0]=='y')
    117                     vote[i][j].c=1;
    118                 else
    119                     vote[i][j].c=0;
    120             }
    121             if(ans<=2){
    122                 for(int j=0;j<ans;j++)
    123                     add(vote[i][j].v,vote[i][j].c^1,vote[i][j].v,vote[i][j].c);
    124             }else
    125                 for(int j=0;j<ans;j++)
    126                     for(int k=0;k<ans;k++)
    127                     {
    128                         if(j==k)
    129                             continue;
    130                         add(vote[i][j].v,vote[i][j].c^1,vote[i][k].v,vote[i][k].c);
    131                     }
    132         }
    133 
    134         memset(res,0,sizeof(res));
    135         printf("Case %d: ",++cnt);
    136         if(!test(n))
    137             printf("impossible
    ");
    138         else {
    139             for(int i=0;i<n;i++)
    140             {
    141                 if(res[i]==0)
    142                     printf("?");
    143                 else if(res[i]==1)
    144                     printf("y");
    145                 else if(res[i]==-1)
    146                     printf("n");
    147             }
    148             printf("
    ");
    149         }
    150     }
    151     return 0;
    152 }
    153 /*
    154 5 3
    155 2 1 y 2 n
    156 3 1 y 3 n 4 y
    157 4 1 n 3 n 4 n 5 y
    158 */
    View Code
  • 相关阅读:
    Cocos2d-x 3.0截屏功能集成
    游戏嵌入Webview网页
    Cocos2dx进阶学习之屏幕适配
    Android如何实现文件下载并自动安装apk包!!!
    LINQ Select变量定义 Expression<Func<TSource, TResult>>
    StringComparison枚举
    .net core DBFirst 生成Model表结构
    .net core反向工程Model生成 配置机密
    axios下载文件.net Core
    EFCore Database-first深入研究
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3247172.html
Copyright © 2011-2022 走看看