题意:

有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. C++:标准模板库vector

    一:介绍 vector是C++标准模板库,是一个容器,底层是数组,为连续内存. 命名空间为std,所属头文件为<vector>   注意:不是<vector.h> vector ...

  2. 20190621-N皇后

    N皇后 难度分类 困难 题目描述 n皇后问题研究的是如何将 n个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n  ...

  3. double check

    http://www.cnblogs.com/limingluzhu/p/5156659.html http://blog.csdn.net/chenchaofuck1/article/details ...

  4. 一个无法解析的外部命令and无法解析的外部符号

    出现错误: 解决: 因为修改了函数定义的参数,但是没有修改函数声明的参数 把参数统一一下就行了

  5. css 小图标 & iconfont 字体图标

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! iconfont 字体图标 我们的需求中,很多时候会看到一些小的图形,或者叫图标,比如天猫网站中:     ...

  6. JS OOP -01 面向对象的基础

    JS面向对象的基础: 1.用定义函数的方式定义类 2.用new操作符获得一个类的实例 3.使用 [ ] 引用对象的属性和方法 4.动态添加,修改,删除对象的属性和方法 5.使用 { } 语法创建无类型 ...

  7. vue 集成jTopo 处理方法

    jTopo 帮助说明网站 http://www.jtopo.com/index.html 使用例子: http://www.jtopo.com/demo/helloworld.html 不建议直接安装 ...

  8. javadoc 自动生成java帮助文档

    用法: javadoc [options] [packagenames] [sourcefiles] 选项: -public 仅显示 public 类和成员 -protected 显示 protect ...

  9. Linux 配置jdk vim和 Linux 基本操作

    1下载jdk tar.gz 安装包(http://www.oracle.com/) 注意安装机器的Linux 是x86(32位)还是x64(64位)的 2使用tar -zxvf jdk.tar.gz解 ...

  10. 南宁AI项目

    1.能了解并对项目整体进度情况有清晰的认识,什么时间点需要完成什么工作项. 2.认识了解项目干系人,能和客户独立沟通交流,理解现场业务,不要一问三不知,什么情况都不了. 3.能推动项目进展和问题及时处 ...