1703:发现它,抓住它

网址如下:

OpenJudge - 1703:发现它,抓住它

测,这题差点让我去世

用了一堆方法来做

后面现学了并查集,用了并查集来做,因为缩短路径的方法不好,还是超时了

后面换了一种缩短路径的方法

先上代码

解法一(TLE)

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;const int maxn = 100001;int kase[maxn], N, M;
vector<int> G[maxn];
bool vis[maxn];void init(void){for(int i = 1; i <= N; i++) G[i].clear();memset(kase, -1, sizeof(kase));
}
void chg(int idx){vis[idx] = true;for(int i = 0; i < G[idx].size(); i++) if(!vis[G[idx][i]]) chg(G[idx][i]);kase[idx] = !kase[idx];
}
void fill(int idx, int b){vis[idx] = true;if(vis[b]) return;for(int i = 0; i < G[idx].size(); i++) if(!vis[G[idx][i]]) fill(G[idx][i], b);
}
void distinguish(int a, int b){if(kase[a] == -1 && kase[b] == -1){kase[a] = 0; kase[b] = 1;}else if(kase[a] == -1){kase[a] = !kase[b];}else if(kase[b] == -1){kase[b] = !kase[a];}else if(kase[a] == kase[b]){memset(vis, 0, sizeof(vis)); chg(a);}G[a].push_back(b); G[b].push_back(a);
}
void ans(int a, int b){if(kase[a] == -1 || kase[b] == -1) printf("Not sure yet.\n");else{memset(vis, 0, sizeof(vis));fill(a, b);if(vis[b]){if(kase[a] == kase[b]) printf("In the same gang.\n");else printf("In different gangs.\n");}else printf("Not sure yet.\n");}
}int main(void)
{int T; scanf("%d", &T);while(T--){scanf("%d%d", &N, &M);init();while(M--){getchar(); char c = getchar();int a, b; scanf("%d%d", &a, &b);if(c == 'A') ans(a, b);else distinguish(a, b);}}return 0;
}

思路

我就是根据已有的情报直接假设哪几个案件是哪个团伙干的

只需要维护这几个案件的关系满足情报就行

但是因为是随意假设的,所以会出现假设完的两个案件与情报不符

这就要改变其中一个案件(0变1或1变0)

或者说“案件图”

因为D a b把这一片案件连起来了

所以都要改

同时,还有一种意外情况,两个案件不在同一个“案件图”上,案件都不为-1(代表未定义)

就需要事先判断二者在同一个“案件图”上


总结
我们需要做的:记录“情报图”,并维护案件的关系与情报相符
两个案件可以判断关系的前提条件:都定义了,且在同一个“情报图”上

但是TLE了

解法二(TLE)

#include<cstdio>
#include<cstring>
using namespace std;const int maxn = 100001;int kase[maxn], N, M;
int color[maxn];
int newcolor;void init(void){memset(kase, -1, sizeof(kase));memset(color, 0, sizeof(color));newcolor = 1;
}
void paint(int Dst, int Src){for(int i = 1; i <= N; i++) if(color[i] == Src) color[i] = Dst;
}
void distinguish(int a, int b){if(kase[a] == -1 && kase[b] == -1){kase[a] = 0; kase[b] = 1; color[a] = color[b] = newcolor++;}else if(kase[a] == -1){kase[a] = !kase[b]; color[a] = color[b];}else if(kase[b] == -1){kase[b] = !kase[a]; color[b] = color[a];}else if(kase[a] == kase[b]){paint(color[a], color[b]);}}
void ans(int a, int b){if(kase[a] == -1 || kase[b] == -1) printf("Not sure yet.\n");else{if(color[a] == color[b]){if(kase[a] == kase[b]) printf("In the same gang.\n");else printf("In different gangs.\n");}else printf("Not sure yet.\n");}
}int main(void)
{int T; scanf("%d", &T);while(T--){scanf("%d%d", &N, &M);init();while(M--){getchar(); char c = getchar();int a, b; scanf("%d%d", &a, &b);if(c == 'A') ans(a, b);else distinguish(a, b);}}return 0;
}

思路

根据上面我所说的,我只是把一个“案件图”涂上了相同的颜色,来标记这些案件属于同一个“案件图”。这样,每次出现两个案件不在同一个“案件图”上,案件都不为-1(代表未定义)的情况,合并“案件图”就只需要把一个“案件图”的颜色涂成另一个“案件图”的

就不需要解法一的vector来记录图的结点之间的联系,减少了内存操作

但是每次重涂就需要遍历所有的案件

重涂数量多了就完蛋

最后还是TLE

解法三(TLE)

#include<cstdio>
#include<cstring>
using namespace std;const int maxn = 100001;int kase[maxn], N, M;
int color[maxn];
int head[maxn], next[maxn];
int newcolor;void init(void){memset(kase, -1, sizeof(kase));memset(color, 0, sizeof(color));memset(head, 0, sizeof(head));memset(next, 0, sizeof(next));newcolor = 1;
}
inline void list_insert(int idx, int color){next[idx] = head[color];head[color] = idx;
}
void paint(int Dst, int Src){for(int i = head[Src]; i; i = next[i]){color[i] = Dst; kase[i] = !kase[i]; list_insert(i, Dst);}
}
void distinguish(int a, int b){if(kase[a] == -1 && kase[b] == -1){kase[a] = 0; kase[b] = 1; color[a] = color[b] = newcolor; list_insert(a, newcolor); list_insert(b, newcolor++);}else if(kase[a] == -1){kase[a] = !kase[b]; color[a] = color[b]; list_insert(a, color[b]);}else if(kase[b] == -1){kase[b] = !kase[a]; color[b] = color[a]; list_insert(b, color[a]);}else if(kase[a] == kase[b]){paint(color[a], color[b]);}}
void ans(int a, int b){if(kase[a] == -1 || kase[b] == -1) printf("Not sure yet.\n");else{if(color[a] == color[b]){if(kase[a] == kase[b]) printf("In the same gang.\n");else printf("In different gangs.\n");}else printf("Not sure yet.\n");}
}int main(void)
{int T; scanf("%d", &T);while(T--){scanf("%d%d", &N, &M);init();while(M--){getchar(); char c = getchar();int a, b; scanf("%d%d", &a, &b);if(c == 'A') ans(a, b);else distinguish(a, b);}}return 0;
}

思路

那优化就很简单了,既然每次重涂都需要遍历所有元素,那么我建立链表,将需要改变的案件记录起来就行了

但是还是TLE,因为数据太大了

解法四(TLE)

#include<cstdio>
#include<cstring>
using namespace std;const int maxn = 100001;int condition[maxn], N, M;
int parent[maxn], rank[maxn];
int newcolor;void init(void){memset(condition, 0, sizeof(condition));memset(rank, 1, sizeof(rank));for(int i = 1; i <= N; i++) parent[i] = i;newcolor = 1;
}
int find(int idx){if(parent[idx] == idx) return idx;return find(parent[idx]);
}
int get_relation(int idx){if(parent[idx] == idx) return 0;return get_relation(parent[idx]) ^ condition[idx];
}
void join(int idx1, int idx2){int prt1 = find(idx1), prt2 = find(idx2);if(prt1 == prt2) return;int r1 = get_relation(idx1), r2 = get_relation(idx2);if(rank[prt1] < rank[prt2]){parent[prt1] = prt2; condition[prt1] = !(r1 ^ r2);}else{if(rank[prt1] == rank[prt2]) rank[prt2]++;parent[prt2] = prt1; condition[prt2] = !(r1 ^ r2);}
}
void ans(int a, int b){int prt1 = find(a), prt2 = find(b);if(prt1 != prt2) printf("Not sure yet.\n");else{int r1 = get_relation(a), r2 = get_relation(b);if(r1 == r2) printf("In the same gang.\n");else printf("In different gangs\n");}
}int main(void)
{int T; scanf("%d", &T);while(T--){scanf("%d%d", &N, &M);init();while(M--){getchar(); char c = getchar();int a, b; scanf("%d%d", &a, &b);if(c == 'A') ans(a, b);else join(a, b);}}return 0;
}

思路

考虑到上面的图的特点:不相交,并且需要合并,还要查找元素的关系

然后我去学了并查集

可以看看这篇博客:【算法与数据结构】—— 并查集-CSDN博客

讲的非常简单易懂

然后我用了并查集,并使用了上面那篇博客里面讲的第二种的缩短路径的方法

其中condition记录案件和父案件的关系

parent和rank的意义见上面那篇博客

然后

还是TLE

我差点裂了

解法五(AC)

#include<cstdio>
#include<cstring>
using namespace std;const int maxn = 100001;int condition[maxn], N, M;
int parent[maxn];
int newcolor;void init(void){memset(condition, 0, sizeof(condition));for(int i = 1; i <= N; i++) parent[i] = i;
}
int find(int idx){if(parent[idx] == idx) return idx;int par = parent[idx];while(parent[par] != par){condition[idx] = condition[idx] ^ condition[par];parent[idx] = parent[par];par = parent[idx];}return find(parent[idx]);
}
void join(int idx1, int idx2){int prt1 = find(idx1), prt2 = find(idx2);if(prt1 == prt2) return;parent[prt1] = prt2;condition[prt1] = !(condition[idx1] ^ condition[idx2]);
}
void ans(int a, int b){int prt1 = find(a), prt2 = find(b);if(prt1 != prt2) printf("Not sure yet.\n");else{if(condition[a] == condition[b]) printf("In the same gang.\n");else printf("In different gangs.\n");}
}int main(void)
{int T; scanf("%d", &T);while(T--){scanf("%d%d", &N, &M);init();while(M--){getchar(); char c = getchar();int a, b; scanf("%d%d", &a, &b);if(c == 'A') ans(a, b);else join(a, b);}}return 0;
}

思路

最后就是这玩意了

用到了上述博客提到的缩短路径的第一种方法

condition的意义和解法四的一样

最后AC了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏AI的创造思路-技术基础-情感计算(2)

上一篇我们介绍了情感计算的基本支持&#xff0c;本篇将呈现情感计算在游戏AI中的使用实例~~~ 目录 7. 情感计算在游戏AI中的运用实例 7.1. RPG游戏中的运用实例 7.1.1. 实例背景 7.1.2. AI情感计算系统 7.1.3. 引导用户执行任务 7.1.4. 推动游戏剧情发展 7.1.5. 实例效…

用Python玩转Excel的五大功能!

在日常的数据处理工作中&#xff0c;Excel无疑是一个强大的工具。然而&#xff0c;当数据量较大或需要自动化处理时&#xff0c;Python凭借其强大的库支持&#xff0c;如pandas和openpyxl&#xff0c;能够更高效地处理Excel文件。 本文将介绍Python中常用的五种Excel操作**&am…

一个用于在虚拟桌面下跑chrome的docker镜像

制作了一个用于跑chrome的docker镜像xvfb-chrome&#xff0c;主要是为了支持能够通过xvfb或者wayland&#xff0c;给chrome提供一个虚拟的桌面环境。 这个镜像主要支持&#xff1a; 将chrome --remote-debugging-port映射到docker的host&#xff0c;可以在host直接访问。支持…

Python办公自动化:增值税发票批量识别和核验

腾讯云免费体验地址: https://console.cloud.tencent.com/api/explorer?Product=ocr&Version=2018-11-19&Action=VatInvoiceVerifyNew 首先进行识别,这里以python为例子 # -*- coding: utf-8 -*- import jsonfrom tencentcloud.common.common_client import Commo…

【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——红黑树

目录 1 -> 红黑树 1.1 -> 红黑树的概念 1.2 -> 红黑树的性质 1.3 -> 红黑树节点的定义 1.4 -> 红黑树的结构 1.5 -> 红黑树的插入操作 1.6 -> 红黑树的验证 1.8 -> 红黑树与AVL树的比较 2 -> 红黑树模拟实现STL中的map与set 2.1 -> 红…

如何理解李彦宏说的“不要卷模型,要卷应用?

背景&#xff1a; 7月4日&#xff0c;2024世界人工智能大会暨人工智能全球治理高级别会议全体会议在上海世博中心举办。在产业发展主论坛上&#xff0c;百度创始人、董事长兼首席执行官李彦宏呼吁&#xff1a;“大家不要卷模型&#xff0c;要卷应用&#xff01;”李彦宏认为&am…

【堆 优先队列】1354. 多次求和构造目标数组

本文涉及知识点 堆 优先队列 LeetCode1354. 多次求和构造目标数组 给你一个整数数组 target 。一开始&#xff0c;你有一个数组 A &#xff0c;它的所有元素均为 1 &#xff0c;你可以执行以下操作&#xff1a; 令 x 为你数组里所有元素的和 选择满足 0 < i < target.…

idea在选定范围搜索

idea在选定范围搜索 CtrlR 在IntelliJ IDEA中&#xff0c;‌如果你想在选定的范围内搜索关键字&#xff0c;‌可以按照以下步骤操作&#xff1a;‌ 首先&#xff0c;‌使用鼠标选中你要搜索关键字的一个范围。‌ 然后&#xff0c;‌使用快捷键CtrlR&#xff08;‌替换元素&am…

掌握JsonConvert.SerializeObject:美化输出与序列化对象的艺术

目录 引言 JsonConvert.SerializeObject简介 参数详解 使用示例 运行结果 结论 结语 引言 在现代软件开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;被广泛用于Web API、数据库存储以及跨平台数据传…

linux信息收集与提权

目录 版本信息收集 kali得一些exp网站 kali自带的searchsploit工具 脏牛提权漏洞&#xff08;改写没有写权限的文件&#xff09; 测试靶场下载链接 sudo提权 上传恶意C脚本进行编译生成dirty的elf文件&#xff0c;也可以在攻击机编译好上传 启动&#xff0c;123456是设…

体验完这款售价29999元起苹果新品,我大受震撼

讲道理&#xff0c;数码圈已经很久没有出现过让人耳目一新的产品了。 整个圈子近些年各家新品逻辑给我的一种感觉是普遍主打循规循距&#xff0c;用高情商话来说那叫稳扎稳打不易出错&#xff0c;而低情商嘛&#xff0c;说白了叫创新精神严重缺失。 「科技最后以换皮为准」这…

C语言学习 关于short和int

&#x1f308; 关于今天的这一part 简单说说关于C中的short 和 int 主要是复盘C语言时候的一个小小的回顾把~&#xff08;内容来自C Primer Plus 第六版&#xff09; &#x1f433;主要是讨论一下两个东西 1️⃣ 在给函数传递参数时&#xff0c;C编译器把short类型的值自动转换…

【CUDA】 Trust基本特性介绍及性能分析

Trust简介 Thrust 是一个实现了众多基本并行算法的 C 模板库,类似于 C 的标准模板库(standard template library, STL)。该库自动包含在 CUDA 工具箱中。这是一个模板库,仅仅由一些头文件组成。在使用该库的某个功能时,包含需要的头文件即可。该库中的所有类型与函数都在命名空…

【linux】 sudo apt update报错——‘由于没有公钥,无法验证下列签名: NO_PUBKEY 3B4FE6ACC0B21F32’

【linux】 sudo apt update报错——‘由于没有公钥&#xff0c;无法验证下列签名&#xff1a; NO_PUBKEY 3B4FE6ACC0B21F32’ 在运行sudo apt update时遇到报错&#xff0c;由于没有公钥&#xff0c;无法验证下列签名&#xff1a; NO_PUBKEY 3B4FE6ACC0B21F32 解决方法&#x…

C++八股(五)之Linux常用命令

目录 一、Linux常用命令有哪些? 二、Linux中查看进程运行状态的指令、tar解压文件的参数。⭐⭐⭐ 三、如何创建一个新的目录?⭐⭐ 四、说说如何以root权限运行某个程序。⭐ 五、linux里如何查看一个想知道的进程?⭐ 六、Linux里如何查看带有关键字的日志文件?⭐ 七、…

Qt:11.输入类控件(QLineEdit-单行文本输入控件、QTextEdit-多行文本输入控件、QComboBox-下拉列表的控件)

一、QLineEdit-单行文本输入控件&#xff1a; 1.1QLineEdit介绍&#xff1a; QLineEdit 是 Qt 库中的一个单行文本输入控件&#xff0c;不能换行。允许用户输入和编辑单行文本。 1.2属性介绍&#xff1a; inputMask 设置输入掩码&#xff0c;以限定输入格式。setInputMask(con…

react学习——25redux实现求和案例(完整版)

1、目录结构 2、count/index.js import React, {Component} from "react"; //引入store,用于获取数据 import store from ../../redux/store //引入actionCreator 专门创建action对象 import {createDecrementAction,createIncrementAction} from ../../redux/coun…

CSS【详解】边框 border,边框-圆角 border-radius,边框-填充 border-image,轮廓 outline

边框 border border 是以下三种边框样式的简写&#xff1a; border-width 边框宽度 —— 数值 px&#xff08;像素&#xff09;,thin&#xff08;细&#xff09;,medium&#xff08;中等&#xff09;,thick&#xff08;粗&#xff09;border-style 边框线型 —— none【默认值…

78. UE5 RPG 创建技能数据并初始化技能ui

在上一篇文章里&#xff0c;我们创建了技能的UI&#xff0c;接下来&#xff0c;我们要考虑如何实现对技能UI的填充&#xff0c;肯定不能直接写死&#xff0c;需要有一些方法去实现技能的更新。我们期望能够创建一个技能数据&#xff0c;然后根据数据通过回调的方式实现数据的更…

GET正常,POST获取不到数据

环境复现 前台&#xff1a; wx.request({url: xxxxxx,method: POST,header: {"content-type": "application/json"},success(res) {console.log(res);},fail(err) {console.error(网络请求失败, err);}}); 后端使用springboot&#xff1a; RequestMappin…