[NOI2001]食物链(并查集拓展域)&& [HAOI2006]旅行(Kruskal)
题目描述
动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A 吃 B,B
吃 C,C 吃 A。
现有 N 个动物,以 1 - N 编号。每个动物都是 A,B,C 中的一种,但是我们并不知道
它到底是哪一种。
有人用两种说法对这 N 个动物所构成的食物链关系进行描述:
第一种说法是“1 X Y”,表示 X 和 Y 是同类。
第二种说法是“2 X Y”,表示 X 吃 Y 。
此人对 N 个动物,用上述两种说法,一句接一句地说出 K 句话,这 K 句话有的是真
的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
• 当前的话与前面的某些真的话冲突,就是假话
• 当前的话中 X 或 Y 比 N 大,就是假话
• 当前的话表示 X 吃 X,就是假话
你的任务是根据给定的 N 和 K 句话,输出假话的总数。
输入格式
从 eat.in 中输入数据
第一行两个整数,N,K,表示有 N 个动物,K 句话。
第二行开始每行一句话(按照题目要求,见样例)
输出格式
输出到 eat.out 中
一行,一个整数,表示假话的总数。
emmmmm, 最近学了并查集, 并查集能维护连通性和传递性, 这道题假如单单用一个并查集来维护谁与谁是同类, 显然无法判断互相吃的情况, 那么就容易想到用三个并查集去维护, 我们把每个动物x拆成3个节点, 分别表示同类域, 捕食域, 天敌域。假如x与y是同类, 那么x, y捕食的物种和天敌都是一样的, 把他们都合并。 而当x吃y时, 合并x的捕食域和y的同类域, x的同类域和y的天敌域, x的天敌域和y的捕食域。 在处理每句话之前, 首先要判断这句话是否为真。
#include <bits/stdc++.h> using namespace std; typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e4 + ;
const int MAXM = 3e3 + ;
const double eps = 1e-; template < typename T > inline void read(T &x) {
x = ; T ff = , ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') ff = -;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << ) + (x << ) + (ch ^ );
ch = getchar();
}
x *= ff;
} template < typename T > inline void write(T x) {
if (x == ) {
putchar('');
return ;
}
if (x < ) putchar('-'), x = -x;
static T tot = , ch[];
while (x) {
ch[++tot] = x % + '';
x /= ;
}
while (tot) putchar(ch[tot--]);
} int n, m, ans, fa[MAXN * ]; inline int get(int x) {
return x == fa[x] ? x : fa[x] = get(fa[x]);
} int main() {
// freopen("1.in", "r", stdin);
read(n); read(m);
for (int i = ; i <= n * ; ++i) fa[i] = i;
while (m--) {
// printf("ans = %d\n", ans);
int op, x, y;
read(op); read(x); read(y);
if (x > n || y > n) {
++ans;
continue;
};
if (op == ) {
if (get(x + n) == get(y) || get(x) == get(y + n)) ++ans;
else {
fa[get(x)] = get(y);
fa[get(x + n)] = get(y + n);
fa[get(x + n + n)] = get(y + n + n);
} } else {
if (get(x) == get(y) || get(x) == get(y + n)) ++ans;
else {
fa[get(x + n)] = get(y);
fa[get(x + n + n)] = get(y + n);
fa[get(x)] = get(y + n + n);
}
}
}
write(ans);
return ;
}
题目描述
Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。Z小镇附近共有N个景点(编号为1,2,3,…,N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。速度变化太快使得游客们很不舒服,因此从一个景点前往另一个景点的时候,大家都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。
输入格式
第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。
最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
输出格式
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
emmmmmm, 刚看到这到题的时候, 我就想到了最小差值生成树, 这是我很早之前就做过的题了, 这个题算法上写着并查集, 我当时就想Kruskal和并查集有什么关系, 就专心致志的打我的dfs去了(我丢, 我好sb。。。),dfs的思路还是很容易想到的, 从s这个点开始枚举每一条路径, 把路径上所有边的最大最小值都记录下来, 当到t这个点是时候比较就可以了, 然后我就神奇的MLE, 在一些神仙讨论是数组开小还是爆内存的时候, 我默默地把dfs改成bfs, 结果依然MLE。 算了, 放弃这个暴力吧。 一位大佬提醒我一句, 把每条边加进去, 判断图是否连通。 此时我好像幡然醒悟, 这不就是一个裸的Kruskal嘛, 然后, 我也就真的打了一个Kruskal, 我丢, 我是没睡醒嘛, (其实确实有点瞌睡), 稍作修改就A掉了。 可以说这是一道写过的题了, 我甚至还hack正解, 在以后的学习中还是要学以致用啊。。。。
#include <bits/stdc++.h> using namespace std; typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e5 + ;
const int MAXM = 3e3 + ;
const double eps = 1e-; template < typename T > inline void read(T &x) {
x = ; T ff = , ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') ff = -;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << ) + (x << ) + (ch ^ );
ch = getchar();
}
x *= ff;
} template < typename T > inline void write(T x) {
if (x == ) {
putchar('');
return ;
}
if (x < ) putchar('-'), x = -x;
static T tot = , ch[];
while (x) {
ch[++tot] = x % + '';
x /= ;
}
while (tot) putchar(ch[tot--]);
} //bool cur1; int n, m, s, t, q1, q2, fa[MAXN];
struct tree {
int x, y, v;
bool operator < (const tree &a) const {
return v < a.v;
}
}T[]; inline int gcd(int x, int y) {
return x == ? y : gcd(y % x, x);
} inline int get(int x) {
return fa[x] == x ? x : fa[x] = get(fa[x]);
} inline void Kruskal(int ss) {
for (int i = ; i <= n; ++i) {
fa[i] = i;
}
int maxx = -INF, minn = INF;
for (int i = ss; i <= m; ++i) {
int xx = get(T[i].x), yy = get(T[i].y);
if (xx != yy) {
fa[xx] = yy;
maxx = max(maxx, T[i].v);
minn = min(minn, T[i].v);
}
xx = get(s), yy = get(t);
if (xx == yy) break;
}
int xx = get(s), yy = get(t);
if (xx == yy) {
if ((double) maxx / minn < (double) q1 / q2)
q1 = maxx, q2 = minn;
}
} int main() {
read(n), read(m);
for (int i = ; i <= m; ++i) {
read(T[i].x);
read(T[i].y);
read(T[i].v);
}
read(s); read(t);
sort(T + , T + m + );
q1 = INF, q2 = ;
for (int i = ; i <= m; ++i) Kruskal(i);
if (q1 == INF) puts("IMPOSSIBLE");
else {
int g = gcd(q1, q2);
q1 /= g, q2 /= g;
write(q1);
if (q2 != ) putchar('/'), write(q2);
}
return ;
}
[NOI2001]食物链(并查集拓展域)&& [HAOI2006]旅行(Kruskal)的更多相关文章
- 【Luogu P2024&P1892】食物链&团伙(并查集拓展域)
Luogu P1892 Luogu P2024 这两道一眼看过去很容易发现可以用并查集来做--但是当我们仔细阅读题面后,会发现其实并没有那么简单. 我们知道并查集可以很轻松地维护具有传递性的信息,也就 ...
- P2024 [NOI2001]食物链 并查集
题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...
- Luogu P2024 [NOI2001]食物链 | 并查集
题目链接 思路:并查集,因为一开始我们并不知道每一只动物是哪一个种类的,所以我们干脆建立三倍于n的空间,1~n这三分之一用来存第i只动物是A的情况,n+1~2n这三分之一用来存第(i-n)只动物是B的 ...
- POJ 1703 Find them, Catch them(并查集拓展)
Description The police office in Tadu City decides to say ends to the chaos, as launch actions to ro ...
- 编程算法 - 食物链 并查集 代码(C)
食物链 并查集 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种 ...
- C++食物链【NOI2001】 并查集+建虚点
B. 食物链[NOI2001] 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了 ...
- 【poj1182】食物链--并查集扩展域
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 109341 Accepted: 33191 Description 动物 ...
- [poj1182]食物链(并查集+补集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64841 Accepted: 19077 Description ...
- POJ 1182 (经典食物链 /并查集扩展)
(參考他人资料) 向量偏移--由"食物链"引发的总结 http://poj.org/problem?id=1182这道食物链题目是并查集的变型.非常久曾经做的一次是水过的,这次 ...
随机推荐
- 基于操作系统原理的Red Hat Linux的基本操作
一.实验目的 1.了解Linux操作系统的启动与登录方法. 2.掌握Red Hat Linux图形用户界面下的基本操作. 3.学会Red Hat Linux基本设置. 二.实验内容 1. 登录 2. ...
- Eureka Server不剔除已关停的节点的问题
由于Eureka拥有自我保护机制,当其注册表里服务因为网络或其他原因出现故障而关停时,Eureka不会剔除服务注册,而是等待其修复.这是AP的一种实现. 自我保护机制:Eureka Server在运行 ...
- JVM 调优 - jstat
Java命令学习系列(四)——jstat 2015-07-31 分类:Java 阅读(11041) 评论(1) 阿里大牛珍藏架构资料,点击链接免费获取 jstat(JVM Statistics Mon ...
- 架构——android架构演进概述
随着业务的发展和技术的变更,Android开发也经历了以下几个发展阶段: 看似高大上的名词,其实遵循着最简单的原则:分而治之(如何划分就是"架构",简单的事情如何串在一起就是&qu ...
- vue 引入 fontawesome 报错 Could not find one or more icon(s) 解决
在 vue 项目中引用 fontawesome , 按照官方说明如下步骤操作 1. 终端中执行 $ npm i --save @fortawesome/fontawesome-svg-core $ n ...
- Linux之修改系统密码
目录 Linux之修改系统密码 参考 RHEL6修改系统密码 RHEL7修改系统密码 Linux之修改系统密码
- 一个原生JS实现的不太成熟的贪吃蛇游戏
一个初初初初级前端民工 主要是记录一下写过的东西,复习用 大佬们如果看到代码哪里不符合规范,或者有更好写法的,欢迎各位批评指正 十分感谢 实现一个贪吃蛇游戏需要几步? 1.有地图 2.有蛇 3.有食物 ...
- Redis的持久化机制是什么?各自的优缺点?
Redis 提供两种持久化机制 RDB 和 AOF 机制: 1.RDBRedis DataBase)持久化方式:是指用数据集快照的方式半持久化模式) 记录 redis 数据库的所有键值对,在某个时间点 ...
- Scala 学习笔记之集合(3)
建立一个Java类,为了演示Java集合类型向Scala集合的转换: import java.util.ArrayList; import java.util.List; public class S ...
- [TLSR8267] 泰凌微 telink tlsr8267 ble ADC 用法浅谈
1.读 datasheet 在<DS_TLSR8267-E21_Datasheet for Telink BLE SoC TLSR8267.pdf>第11章详细介绍了ADC相关属性及参数. ...