[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这道食物链题目是并查集的变型.非常久曾经做的一次是水过的,这次 ...
随机推荐
- Android Studio [水平布局LinearLayout]
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Vue.js+vue-element搭建属于自己的后台管理模板:什么是Vue.js?(一)
Vue.js+vue-element搭建属于自己的后台管理模板:Vue.js是什么?(一) 前言 本教程主要讲解关于前端Vue.js框架相关技术知识,通过学习一步一步学会搭建属于自己的后台管理模板,并 ...
- PHPstorm出现的端口号错误问题(502)
咔咔咔-听好 PhpStorm的默认端口是63342,但是在浏览器会提示502错误. 同时Phpstorm右下角会报错:Please ensure that configured PHP Interp ...
- Event Hub小白入门指南
Event Hub事件中心 本文的目的在于用最白的大白话,让你从“完全不懂”开始,理解什么是分布式大数据流平台Event Hub,并且理解它的关键概念,并且初步理解其收发数据API. 定义,Event ...
- SpringBoot 整合 MyBatis-Plus 入门体验
一.前言 本文小编将基于 SpringBoot 整合 MyBatis-Plus , MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上做增强并且不改变原本功能 ...
- 【Java】访问mysql数据库视图
数据库连接Connect: package cn.hkwl.zaxq.mysql; import java.sql.Connection; import java.sql.DriverManager; ...
- php企业微信获取员工userid以及打卡信息
企业微信可以通过部门列表获取部门下的员工信息,从而获取到员工的userid //首先获取需要的access_token $access_token = json_decode($this->ge ...
- jsonp 跨域Uncaught SyntaxError: Unexpected token :解决方法
[jQuery]Ajax实现跨域访问JSON Ajax跨域访问JSON 环境:.net4.0+jQuery+JSON.net 因为在跨域实现,所以这里新建网站,这个网站只需要Ashx文件 public ...
- Lombok中关于@Data的使用
当你在使用 Lombok 的 @Data 注解时,其实会有一些坑需要关注,今天就让我们来见识一下. Lombok 先来简单介绍一下 Lombok ,其官方介绍如下: Project Lombok ma ...
- 渗透测试-基于白名单执行payload--Cmstp
0x01 Cmstp简介 Cmstp安装或删除“连接管理器”服务配置文件.如果不含可选参数的情况下使用,则 cmstp 会使用对应于操作系统和用户的权限的默认设置来安装服务配置文件. 微软官方文档: ...