博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
F - True Liars - poj1417(背包+并查集)
阅读量:4330 次
发布时间:2019-06-06

本文共 2121 字,大约阅读时间需要 7 分钟。

题意:有这么一群人,一群好人,和一群坏人,好人永远会说实话,坏人永远说假话,现在给你一组对话和好人与坏人的数目P1, P2。
数据里面的no是A说B是坏人, yes代表A说B是好人,就是这样,问题能不能从这些话里面得出来唯一的解,就是可以确定谁是好人谁是坏人,如果不能输出no,如果可以输出所有的好人。
分析,可以把这些人依据他们中的关系分成几个小集合,集合里面保存两类人的数目,然后DP求出来好人或者坏人是不是唯一的即可,‘
注意并查集时候可以这么认为凡是yes都是同类,no都是异类
///

 #include<iostream>

#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<
string.h>
#include<queue>
using 
namespace std;
const 
int maxn = 
605;
struct people
{
    
int father, relation;
    
int same, other;
//
同类数目,和异类数目
    
int True;
//
是说谎者还是诚实者
}p[maxn];
int dp[maxn][maxn];
int Find(
int x)
{
    
int k = p[x].father;
    
if( p[x].father != x )
    {
        p[x].father = Find(k);
        p[x].relation = (p[x].relation+p[k].relation)%
2;
    }
    
return p[x].father;
}
int main()
{
    
int M, T, L;
    
while(scanf(
"
%d%d%d
", &M, &T, &L), M+T+L)
    {
        
int i, j, u, v, ru, rv, ok=
0, d, N=T+L, k=
1;
        
char s[
10];
int f[maxn];
//
f记录最后小集体的头结点
        
for(i=
0; i<=N; i++)
        {
            p[i].father = i;
            p[i].other = 
0;
            p[i].same = 
1;
//
自己和自己是同类,所以最少也有一个
            p[i].relation = 
0;
            p[i].True = 
0;
        }
        
while(M--)
        {
            scanf(
"
%d%d%s
", &u, &v, s);
            
if(ok)
continue;
            ru = Find(u), rv = Find(v);
            
if(s[
0] == 
'
y
')
                d = 
0;
//
0表示同类,1表示异类
            
else d = 
1;
            
if(ru == rv && (p[v].relation+p[u].relation)%
2 != d)
                ok = 
1;
            
else 
if(ru != rv)
            {
                p[ru].father = rv;
                p[ru].relation = (p[u].relation+p[v].relation+d)%
2;
            }
        }
        
if(!ok)
//
有可能说的话有矛盾
        {
            
for(i=
1; i<=N; i++)
            {
                u = Find(i);
                
if(u == i)
                    f[k++] = i;
                
else
                {
                    p[u].other += p[i].relation;
                    p[u].same += 
1-p[i].relation;
                }
            }
            memset(dp, 
0
sizeof(dp));
            dp[
1][ p[ f[
1] ].same ] += 
1;
            dp[
1][ p[ f[
1] ].other ] += 
1;
            
for(i=
2; i<k; i++)
            {
                u = f[i];
                
for(j=
0; j<=N; j++)
                {
                    
if(dp[i-
1][j])
                    {
                        dp[i][ p[u].same+j ] += dp[i-
1][j];
                        dp[i][ p[u].other+j ] += dp[i-
1][j];
                    }
                }
            }
        }
        
if(dp[k-
1][L] != 
1 || ok)
            printf(
"
no\n
");
        
else
        {
            
for(i=k-
1; i>
0; i--)
            {
                u = f[i];
                v = p[u].same;
                
if( (i!=
1 && dp[i-
1][T-v] != 
0) || (i==
1 && T==v) )
                {
                    p[u].True = 
1;
                    T -= v;
                }
                
else
                    T -= p[u].other;
            }
            
for(i=
1; i<=N; i++)
            {
                u = p[i].father;
                
if(p[u].True && !p[i].relation || p[u].True==
0 && p[i].relation)
                    printf(
"
%d\n
", i);
            }
            printf(
"
end\n
");
        }
    }
    
return 
0;
}
/*
1 1 1
1 2 yes

*/ 

转载于:https://www.cnblogs.com/liuxin13/p/4671318.html

你可能感兴趣的文章
【[HNOI2004]L语言】
查看>>
python 之 基础
查看>>
kvm初体验之三:vm的安装及管理
查看>>
【Vue】详解Vue组件系统
查看>>
贪心算法1001
查看>>
SQL语句
查看>>
关于pictureBox绑定图像,并保存图像到数据库进行读写
查看>>
a.Baby Coins
查看>>
Jdk1.8+Eclipse+MySql+Tomcat开发Java应用的环境搭建
查看>>
Javascript 获取页面中元素的高度和宽度
查看>>
Python开发-【第二篇】--if条件语句
查看>>
linux crontab 定时器
查看>>
Html知识点
查看>>
Struts2 国际化资源表达式用法
查看>>
Python 之map、filter、reduce
查看>>
hdu1067
查看>>
2019年春季学期第四周作业
查看>>
公司web安全等级提升
查看>>
[BZOJ3224]普通平衡树(旋转treap,STL-vector)
查看>>
C++ - 派生类强制转换为基类
查看>>