【题目链接】:http://hihocoder.com/problemset/problem/1516

【题意】

【题解】



状态压缩DP+bfs

这个过河问题能用bfs来搞.涨知识了;

首先;

16个人

容易想到用0..216−1来表示3处地方的状态;

即这一边的岸,船上,以及对岸;

对于岸上;

只需要这状态里面,能攻击人的人存在,且它攻击的对象也存在,且能管住这个攻击的人的人不在,则这个状态就是不符合要求的;

而对于船上;

则需要一个掌舵人,否则不行;

然后对于岸上的情况船上的情况也要满足;

还有就是船上的人数的限制了;

设f[i][0..1]分别表示某一边状态为i,然后船在某一边(用0和1表示)的最少渡河次数;

f[(1< < n)-1][0]=0;

然后每次枚举到对岸的人是哪些就好;

枚举的方法很巧妙;

for (int i = (1< < n)-1;i;i=(i-1)&now)

这个&运算保证了,只有当前存在的人才能过去;然后又能把所有情况都涉及到;

最后输出f[(1< < n)-1][1]

程序中can[i]判断i这状态能不能在船上

can2[i]判断i这个状态能不能在岸上



【Number Of WA】



0



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 18;
const int MAX = 7e4; int n,m,a,b,c,all;
int son[N],fat[N],boa;
bool can[MAX],can2[MAX];
int f[MAX][2];
queue <pii> dl; bool check(int statu)
{
if ((statu&boa)==0) return false;
int cnt = 0;
rep1(i,0,n-1)
{
if ((statu>>i)&1)
{
cnt++;
if (((fat[i]&statu)==0) && (son[i]&statu))
return false;
}
}
if (cnt>m) return false;
return true;
} bool check2(int statu)
{
rep1(i,0,n-1)
{
if ((statu>>i)&1)
{
if (((fat[i]&statu)==0) && (son[i]&statu))
return false;
}
}
return true;
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
cin >> n >> m;
cin >> a >> b >> c;
int x,y;
rep1(i,1,a)
{
cin >> x >> y;
son[x] |= (1<<y);
}
rep1(i,1,b)
{
cin >> x >> y;
fat[y]|= (1<<x);
}
rep1(i,1,c)
{
cin >> x;
boa |= (1<<x);
}
all = (1<<n)-1;
rep2(i,all,0)
{
can[i] = check(i);
can2[i] = check2(i);
}
if (!can2[all]) return cout <<-1<<endl,0;
ms(f,255);
f[all][0] = 0;
dl.push(mp(all,0));
while (!dl.empty())
{
int s = dl.front().fi,k = dl.front().se;dl.pop();
for (int left = s;left;left=(left-1)&s)
{
if (can[left] && can2[all^s^left] && can2[s^left] && can2[all^s])
{
int status = all^s^left;
if (f[status][k^1]==-1)
{
f[status][k^1] = f[s][k]+1;
dl.push(mp(status,k^1));
}
}
}
}
cout << f[all][1] << endl;
return 0;
}

【[Offer收割]编程练习赛15 C】过河问题的更多相关文章

  1. [Offer收割]编程练习赛15 B.分数调查[加权并查集]

    #1515 : 分数调查 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的学校总共有N名学生,编号1-N.学校刚刚进行了一场全校的古诗文水平测验. 学校没有公布测 ...

  2. [Offer收割]编程练习赛15 A.偶像的条件[贪心]

    #1514 : 偶像的条件 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的学校正面临着废校的大危机.面对学校的危机,小Hi同学们决定从ABC三个班中各挑出一名同 ...

  3. 【[Offer收割]编程练习赛15 B】分数调查

    [题目链接]:http://hihocoder.com/problemset/problem/1515 [题意] [题解] 带权并查集 relation[x]表示父亲节点比当前节点大多少; 对于输入的 ...

  4. 【[Offer收割]编程练习赛15 A】 偶像的条件

    [题目链接]:http://hihocoder.com/contest/offers15/problem/1 [题意] [题解] 把3个数组的元素全都合并在一个数组里面; (当然你要记录每个数字原本是 ...

  5. hihocoder [Offer收割]编程练习赛4

    描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...

  6. hihocoder [Offer收割]编程练习赛61

    [Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...

  7. [Offer收割]编程练习赛46

    [Offer收割]编程练习赛46赛后题解 A.AEIOU 分析

  8. [Offer收割]编程练习赛23-freeloop

    A. H国的身份证号码I dfs裸题. 时间复杂度\(O(n^k)\). #include <bits/stdc++.h> #define FOR(i,a,b) for (int i=a; ...

  9. hihoCoder[Offer收割]编程练习赛1题目解析

    题目1 : 九宫 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi近期在教邻居家的小朋友小学奥数.而近期正好讲述到了三阶幻方这个部分,三阶幻方指的是将1~9不反 ...

随机推荐

  1. ZOJ 3814 Sawtooth Puzzle (2014年牡丹江赛区网络赛F题)

    1.题目描写叙述:点击打开链接 2.解题思路:本题是一道隐式图的搜索题目.一般来说,这类题目首先要定义状态,接下来是弄清楚状态怎样转移,以及状态怎样判重,怎样推断当前状态是否和目标状态同样.至于求解最 ...

  2. Mongodb---记一次事故故障

    2014.06.19.001---故障报告 事故发生时间 事故简述 事故责任方 是否解决 19:21-20:15 IISserverD盘即将溢出 是 一.事故描写叙述: 在19:21收到警报.显示II ...

  3. Openstack能解决这些问题吗?请各位大侠一起来讨论

    1.10万规模的虚拟机,每一个虚拟机能够在不论什么一个计算节点上启动,该怎样做?计算,存储,网络都是怎么拉通与配合的? 2.用户怎样自己定义业务网络,怎样解决网络不够用的情况?正常就4096个vlan ...

  4. JS中split使用方法和数组中元素的删除

    JS中split使用方法和数组中元素的删除 JS中split使用方法 <script language="javascript"> function spli(){ d ...

  5. Middle-help 终极实现元素水平垂直居中

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  6. UVA 10006(素数打表+快速幂)

    当今计算机科学的一个重要的领域就是密码学.有些人甚至认为密码学是计算机科学中唯一重要的领域,没有密码学生命都没有意义. 阿尔瓦罗就是这样的一个人,它正在设计一个为西班牙杂烩菜饭加密的步骤.他在加密算法 ...

  7. PCB 电测试--测试点数自动输出到流程指示中(读取TGZ Stephdr文件)

    好不容易实现了 <PCB 无需解压,直接读取Genesis TGZ指定文件 > 正好这里有一项需求:PCB电测试--测试点数自动输出到流程指示中 一.自动输出测试点小结; 1.由于历史原因 ...

  8. 深入理解Redis(一)——高级键管理与数据结构

    引语 这个章节主要讲解了三部分内容: 如何设计并管理Redis的键以及与其关联的数据结构: 了解并使用Redis客户端对象映射器: 介绍如何利用大O标记来评估Redis性能. 键与数据结构 键 我们先 ...

  9. MyBatis动态条件、一对多、整合spring(二)

    输入映射和输出映射 Mapper.xml映射文件定义了操作数据库的sql,每一个sql是一个statement,映射文件是mybatis的核心. parameterType输入类型 1.传递简单类型 ...

  10. OpenCV:OpenCV目标检测Hog+SWindow源代码分析

    参考文章:OpenCV中的HOG+SVM物体分类 此文主要描述出HOG分类的调用堆栈. 使用OpenCV作图像检测, 使用HOG检测过程,其中一部分源代码如下: 1.HOG 检测底层栈的检测计算代码: ...