LA 4452 The Ministers' Major Mess(2-SAT)

来源:互联网 发布:javascript与jsp 编辑:程序博客网 时间:2024/05/01 08:51

题意: n 个人对m个方案投票 。 每个人最多对4个方案投票, 问是否存在一种决定  , 使每个人都有超过一半的建议被采用 。 且哪些方案的态度是确定的。

这个题并不难, 只要简单的分析一下就可以发现,投票数<=2 的人的建议必须被采用  , 投票数>=3的人的建议最多只能有一个不采用。


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn = 220 ;struct TwoSat{    int n ;    vector<int>G[maxn] ;    void init(int n) {        this->n = n;        memset(mark , 0,sizeof(mark)) ;        for(int i=0 ;i<=2*n ;i++) G[i].clear() ;    }    void add_edge(int u ,int v)    {        G[u].push_back(v) ;    }    bool mark[maxn];    int S[maxn] , cnt ;    bool dfs(int u){        if(mark[u^1]) return false ;        if(mark[u]) return true ;        mark[u] = true;        S[cnt++] = u ;        int sz = G[u].size();        for(int i=0 ;i<sz ;i++) {            int v = G[u][i] ;            if(!dfs(v)) return false ;        }        return true;    }    bool check()    {        for(int i=0 ;i<2*n ;i+=2)        {            if(mark[i] && mark[i^1]) return false ;            if(!mark[i] && !mark[i^1])            {                cnt = 0;                if(!dfs(i))                {                    while(cnt >0) mark[S[--cnt]] = false ;                    if(!dfs(i^1)) return false ;                }            }        }        return true ;    }    bool ok(int u)    {        memset(mark, 0 ,sizeof(mark));        cnt = 0;        if(!dfs(u)) return false ;        return check() ;    }    char ans[maxn] ;    bool solve()    {        if(!check()) return false ;        for(int i=0 ;i<2*n ; i+=2)        {                 bool a = ok(i) , b = ok(i^1) ;                 if(a && b) ans[i/2] = '?' ;                 else if(a) ans[i/2] = 'n' ;                 else if(b) ans[i/2] = 'y' ;                 else return false ;        }        return true ;    }};TwoSat T ;int main(){    //freopen("in.txt" ,"r" ,stdin);    int B , M ;    int cas = 0;    while(cin>>B>>M && B){        cas ++ ;        T.init(B) ;        while(M--)        {            int k , a[10] ,i ;            char s[5] ;            cin>>k ;            for(int t = 1 ;t<=k ;t++)            {                cin>>i>>s ;                i-- ;                if(s[0] == 'y') a[t] = i*2+1;                else a[t] = i*2 ;            }            switch (k)            {                    case 1 :                        T.add_edge(a[1]^1 , a[1]) ;                    break ;                    case 2 :                        T.add_edge(a[1]^1 , a[1]) ;                        T.add_edge(a[2]^1 , a[2]) ;                    break ;                    case 3 :                        for(int i=1 ;i<=3 ;i++)                            for(int j=1 ;j<=3 ;j++) if(i != j)                            {                                T.add_edge(a[i]^1 , a[j]) ;                            }                    break ;                    case 4 :                        for(int i=1 ;i<=4 ;i++)                            for(int j=1 ;j<=4 ;j++) if(i != j)                            {                                T.add_edge(a[i]^1 , a[j]) ;                            }                    break ;            }        }        cout<<"Case "<<cas<<": ";        if(!T.solve())  cout<<"impossible"<<endl ;        else        {            for(int i=0 ;i<B ;i++) cout<<T.ans[i] ;            cout<<endl ;        }    }    return 0;}


0 0
原创粉丝点击