题意:

有n个房间和m扇门,每扇门有且仅有一把钥匙
有k个人度过了两天,在第一天开始的时候所有的门都是关闭的,在第二天结束的时候,所有的门也都是关闭的
在这两天内,每个人可以执行如下操作若干次:
关上一扇门(前提:他有这扇门的钥匙,且这扇门与当前房间相连)
打开一扇门(前提:他有这扇门的钥匙,且这扇门与当前房间相连)
将自己手上的一些钥匙给与他同处于一间房里的其他人
走向一个与当前房间相连、且门是打开的房间
给出第一天开始前和第二天结束后每个人的位置及拥有的钥匙
判断是否可行

题解:

直接想不太好做。

转化一下:

可以发现,如果有解,一定可以把能打开的门都打开,在关回去。

而开和关是互逆的,所以,可以理解为两天都把能打开的门都打开。

如果都打开后,两天结果一样,则有解。

一样就是指打开的门相同,每个房间,人,钥匙所属集合分别相同。

这样就好做了。

暴力枚举能打开的边,用并查集维护每个集合的钥匙,暴力合并。

可以发现,枚举\(m\)次就够了。每次暴力合并复杂度为\(O(m)\),总时间复杂度为\(O(m^2)\)。

代码:

#include <stdio.h>
#include <map>
using namespace std;
#define ull unsigned long long
#define se 13131
int u[1005],v[1005],fa[1005],n,m,k;
bool zt[1005][1005];
int getv(int x) {
if (x == fa[x]) return x;
fa[x] = getv(fa[x]);
return fa[x];
}
void merge(int x, int y) {
x = getv(x);
y = getv(y);
if (x == y) return;
if (x < y) {
int t = x;
x = y;
y = t;
}
fa[x] = y;
for (int i = 1; i <= m; i++) {
if (zt[x][i]) zt[y][i] = true;
}
}
ull ha(char zf[1005]) {
ull rt = 0;
for (int i = 0; zf[i] != 0; i++) rt = rt * se + zf[i];
return rt;
}
map < ull,int > mp;
char zf[1005];
int wz[1005],rw[1005],yw[1005];
int w2[1005],r2[1005],y2[1005];
bool b1[1005],b2[1005];
int main() {
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 1; i <= m; i++) scanf("%d%d", &u[i], &v[i]);
for (int i = 1; i <= k; i++) {
int a,s;
scanf("%s%d%d", zf, &a, &s);
rw[i] = a;
mp[ha(zf)] = i;
for (int j = 0; j < s; j++) {
int b;
scanf("%d", &b);
zt[a][b] = 1;
yw[b] = a;
}
}
for (int a = 1; a <= m; a++) {
for (int i = 1; i <= m; i++) {
if (!b1[i] && (zt[getv(u[i])][i] || zt[getv(v[i])][i])) {
merge(u[i], v[i]);
b1[i] = true;
}
}
}
for (int i = 1; i <= n; i++) wz[i] = getv(i);
for (int i = 1; i <= m; i++) yw[i] = getv(yw[i]);
for (int i = 1; i <= k; i++) rw[i] = getv(rw[i]);
for (int i = 1; i <= n; i++) {
fa[i] = i;
for (int j = 1; j <= m; j++) zt[i][j] = 0;
}
for (int i = 1; i <= k; i++) {
int a,s;
scanf("%s%d%d", zf, &a, &s);
r2[mp[ha(zf)]] = a;
for (int j = 0; j < s; j++) {
int b;
scanf("%d", &b);
zt[a][b] = 1;
y2[b] = a;
}
}
for (int a = 1; a <= m; a++) {
for (int i = 1; i <= m; i++) {
if (!b2[i] && (zt[getv(u[i])][i] || zt[getv(v[i])][i])) {
merge(u[i], v[i]);
b2[i] = true;
}
}
}
for (int i = 1; i <= n; i++) w2[i] = getv(i);
for (int i = 1; i <= m; i++) y2[i] = getv(y2[i]);
for (int i = 1; i <= k; i++) r2[i] = getv(r2[i]);
bool zd = false;
for (int i = 1; i <= n; i++) {
if (wz[i] != w2[i]) zd = true;
}
for (int i = 1; i <= n; i++) {
if (rw[i] != r2[i]) zd = true;
}
for (int i = 1; i <= n; i++) {
if (yw[i] != y2[i]) zd = true;
}
for (int i = 1; i <= m; i++) {
if (b1[i] != b2[i]) zd = true;
}
if (zd) printf("NO");
else printf("YES");
return 0;
}

CF46F Hercule Poirot Problem的更多相关文章

  1. Codeforces 图论题板刷(2000~2400)

    前言 首先先刷完这些在说 题单 25C Roads in Berland 25D Roads not only in Berland 9E Interestring graph and Apples ...

  2. 1199 Problem B: 大小关系

    求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...

  3. No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

    Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...

  4. C - NP-Hard Problem(二分图判定-染色法)

    C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144 ...

  5. Time Consume Problem

    I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...

  6. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  7. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...

  8. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4032  Solved: 1817[Submit] ...

  9. [LeetCode] Water and Jug Problem 水罐问题

    You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...

随机推荐

  1. Office 2016、2019 与 Office 365 的区别

    点开观看更清晰:

  2. P3205 [HNOI2010]合唱队

    题目点这里 题面: 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共N个人,第i个人的身高为Hi米(1000<=Hi ...

  3. unittest之二makeSuite\testload\discover及测试报告teseReport

    测试套件suite除了使用addTest以外,还有使用操作起来更更简便的makeSuite\testload\discover 1.makeSuite,创建测试套件,传的参数是要执行的测试用例所在的类 ...

  4. 关于UBOOT,LINUX内核编译,根文件系统的15个小问题

    (1)内核默认运行地址和加载地址在哪里设置? 由 arch/arm/kernel/vmlinux.lds.S 生成的 arch/armkernel/vmlinux.lds决定   (2)从FLASH什 ...

  5. 区间dp最长回文子序列问题

    状态转移方程如下: 当i > j时,dp[i,j]= 0. 当i = j时,dp[i,j] = 1. 当i < j并且str[i] == str[j]时,dp[i][j] = dp[i+1 ...

  6. Visual Studio 开发大量 JavaScript 代码项目程序崩溃的解决方案

    最近公司做新项目,基于 Bootstrap.AngularJS 和 kendo 开发一套后台的管理系统,在项目中使用了大量的 JavaScript 文件,这两天 Visual Studio 2015 ...

  7. 转:让PIP源使用国内镜像,提升下载速度和安装成功率

    转载,自己记录使用,原文http://www.cnblogs.com/microman/p/6107879.html 对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太 ...

  8. ROUTE: route addition failed

    ROUTE: route addition failed 1)报FlushIpNetTable failed on interface错误 应对:以管理员身份运行OpenV-P-N 2)报Warnin ...

  9. TypeScript入门九:TypeScript的模块

    关于TypeScript模块的基本使用方法 Ts的模块化语法与ES6的语法基本是一致(关于一些细节特性没有测试,请各自自行测试),然后再由tsconfig.json的module字段来描述转码类型,具 ...

  10. 【hadoop】细读MapReduce的工作原理

    前言:中秋节有事外加休息了一天,今天晚上重新拾起Hadoop,但感觉自己有点烦躁,不知后续怎么选择学习Hadoop的方法. 干脆打开电脑,决定: 1.先将Hadoop的MapReduce和Yarn基本 ...