题意: 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;
}