• UVALive


    题目链接

    题意:有n个决议和m个人,每个人给至多4个方案投票,问是否存在一种方案使每个人超过一半的投票生效

    当一个人投票数小于等于2时,他的每一票都必须生效,否则至多有一票不生效,“至多有一票不生效”等价于“任意两票不能同时不生效”,这样就转化成了一个2-SAT问题

    题目还要求输出每一种方案的所有可能,逐一枚举然后2-SAT即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef double db;
     5 const int N=1e5+10;
     6 struct TWO_SAT {
     7     int n,hd[N],ne,col[N],sta[N],tp;
     8     struct E {int v,f,g,nxt;} e[N];
     9     void link(int u,int v,int f,int g) {
    10         e[ne]= {v,f,g,hd[u]},hd[u]=ne++;
    11         e[ne]= {u,!g,!f,hd[v]},hd[v]=ne++;
    12     }
    13     void init(int _n) {
    14         n=_n,ne=tp=0;
    15         for(int i=1; i<=n; ++i)hd[i]=-1;
    16     }
    17     bool dfs(int u,int c) {
    18         if(~col[u])return col[u]==c;
    19         col[u]=c,sta[tp++]=u;
    20         for(int i=hd[u]; ~i; i=e[i].nxt) {
    21             int v=e[i].v,f=e[i].f,g=e[i].g;
    22             if(f==col[u]&&!dfs(v,g))return 0;
    23         }
    24         return 1;
    25     }
    26     bool check() {
    27         for(int i=1; i<=n; ++i)col[i]=-1;
    28         for(int i=1; i<=n; ++i)if(!~col[i]) {
    29                 tp=0;
    30                 if(!dfs(i,0)) {
    31                     for(; tp; col[sta[--tp]]=-1);
    32                     if(!dfs(i,1))return 0;
    33                 }
    34             }
    35         return 1;
    36     }
    37 } twosat;
    38 struct D {int u; char c;};
    39 int ans[N],n,m,ka,hd[N],ne;
    40 const char* ss=".ny?";
    41 int main() {
    42     while(scanf("%d%d",&n,&m),n) {
    43         twosat.init(n);
    44         while(m--) {
    45             vector<D> vec;
    46             int k;
    47             scanf("%d",&k);
    48             for(int i=0; i<k; ++i) {
    49                 int u;
    50                 char c;
    51                 scanf("%d %c",&u,&c);
    52                 vec.push_back({u,c});
    53             }
    54             if(k<=2) {for(D x:vec)twosat.link(x.u,x.u,x.c!='y',x.c=='y');}
    55             else {
    56                 for(int i=0; i<vec.size(); ++i)
    57                     for(int j=i+1; j<vec.size(); ++j)
    58                         twosat.link(vec[i].u,vec[j].u,vec[i].c!='y',vec[j].c=='y');
    59             }
    60         }
    61         for(int i=1; i<=n; ++i)hd[i]=twosat.hd[i];
    62         ne=twosat.ne;
    63         for(int u=1; u<=n; ++u)ans[u]=0;
    64         for(int u=1; u<=n; ++u)
    65             for(int f=0; f<2; ++f) {
    66                 twosat.link(u,u,!f,f);
    67                 if(twosat.check())ans[u]|=1<<f;
    68                 for(int i=1; i<=n; ++i)twosat.hd[i]=hd[i];
    69                 twosat.ne=ne;
    70             }
    71         bool ok=1;
    72         for(int u=1; u<=n; ++u)if(ans[u]==0)ok=0;
    73         printf("Case %d: ",++ka);
    74         if(!ok)puts("impossible");
    75         else {
    76             for(int u=1; u<=n; ++u)printf("%c",ss[ans[u]]);
    77             puts("");
    78         }
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    小菜编程成长记(四 业务的封装)
    小菜学Flex2(二 currentState初步使用)
    小菜编程成长记(九 反射——程序员的快乐!)
    小菜编程成长记(一 面试受挫——代码无错就是好?)
    小菜编程成长记(六 关于Flex的争论)
    小菜编程成长记(三 复制VS复用)
    104种木马的清除方法
    细节决定成败打电话和发邮件的细节
    MS SQL Server查询优化方法
    美国西点军校最重要的行为准则:没有任何借口
  • 原文地址:https://www.cnblogs.com/asdfsag/p/14610732.html
Copyright © 2020-2023  润新知