T^T的图论

TimeLimit:3000MS  MemoryLimit:256MB
64-bit integer IO format:%lld
已解决 | 点击收藏

收藏题目

Problem Description

有一个坐标系,坐标系上有n个点,在同一行或同一列上的任意两点称为关联的,并且关联属性是可传递的,即A和B关联,B和C关联,则可认为A和C关联,现在问图中是否任意两点都是关联的。

Input

n>=2 && n<=50万

每个点的坐标x、y满足 1<=x、y<=50000

Output

如果是关联的,输出YES,否则,输出NO

SampleInput
NO
YES

分析:根据题目我们需要把具有x和y任选其一相同的,合并在一个集合中一开始想的是先把所有的点按x的大小进行排序,相同的点合并到一个集合中再把所有的点按y的大小进行排序,相同的点合并道一个集合中这样的话刚刚可以在时间限制内卡过去 2900多MS

代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
const int MAXN=5e5+10;
int pre[MAXN];
int num[MAXN];
struct node
{int x;int y;int id;
}poi[MAXN];
int cmp1(node a,node b)
{return a.x<b.x;
}
int cmp2(node a,node b)
{return a.y<b.y;
}
int Find(int x)
{int h,tem;h=x;while(x!=pre[x])x=pre[x];while(h!=x){tem=pre[h];pre[h]=x;h=tem;}return x;
}
void join(int x,int y)
{int p=Find(x);int q=Find(y);if(p!=q){pre[p]=q;num[q]=num[p]+num[q];}
}
int main()
{int n;while(scanf("%d",&n)!=EOF){for(int i=0;i<n;i++){pre[i]=i;num[i]=1;}for(int i=0;i<n;i++){scanf("%d%d",&poi[i].x,&poi[i].y);poi[i].id=i;}sort(poi,poi+n,cmp1);for(int i=1;i<n;i++){if(poi[i].x==poi[i-1].x)join(poi[i-1].id,poi[i].id);}sort(poi,poi+n,cmp2);for(int i=1;i<n;i++){if(poi[i].y==poi[i-1].y)join(poi[i-1].id,poi[i].id);}if(num[Find(0)]==n)puts("YES");else puts("NO");}return 0;
}

看了其他人的代码后发现,可以先对于x的话,统计集合的数量,如果这个x值第一次出现,那么集合必增加。如果已经出现过,那么就能合并到已经出现的集合里面

然后将y排序,y值相同的点,再去看它们的x值是否已经合并到了一个集合,如果不在一个集合,就将它们合并到一个集合里,并且集合的数量减一.

(在这里,我们是根据x的值进行并查集,那么一个开始x值相同的就自动到了一个集合,这种方法可以减少进行集合合并的次数,并节约时间)

代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
const int MAXN=5e5+10;
int pre[MAXN];
int ans;
int vis[MAXN];
struct node
{int x;int y;int id;
}poi[MAXN];
int cmp1(node a,node b)
{return a.x<b.x;
}
int cmp2(node a,node b)
{return a.y<b.y;
}
int Find(int x)
{int h,tem;h=x;while(x!=pre[x])x=pre[x];while(h!=x){tem=pre[h];pre[h]=x;h=tem;}return x;
}
void join(int x,int y)
{int p=Find(x);int q=Find(y);if(p!=q){pre[p]=q;ans--;}
}
int main()
{int n,x1,x2;while(scanf("%d",&n)!=EOF){memset(vis,0,sizeof(vis));for(int i=1;i<=50000;i++)pre[i]=i;ans=0;for(int i=0;i<n;i++)scanf("%d%d",&poi[i].x,&poi[i].y);for(int i=0;i<n;i++){if(!vis[poi[i].x]){vis[poi[i].x]=1;ans++;}}sort(poi,poi+n,cmp2);for(int i=1;i<n;i++){if(poi[i].y==poi[i-1].y){join(poi[i].x,poi[i-1].x);}}if(ans>1)puts("NO");else puts("YES");}return 0;
}
/*4
1 3
4 5
5 3
4 3
NO
*/

转载于:https://www.cnblogs.com/a249189046/p/7458607.html

FJUT 2351 T^T的图论(并查集)相关推荐

  1. 图论 + 并查集 ----最小生成树重构图 + 可撤销并查集 + set启发式合并 时间线上的离线求解 D. Graph and Queries

    解题思路 题目大意: 就是给你一个无向图,每个点都有一个权值,和qqq次询问 每次询问有两种操作 1 x:就询问从x点出发,能访问到的最大权值是多少,并把最大权值那个点的权值设置为0 2 x:就是删除 ...

  2. 牛客小白月赛25 C-白魔法师 ( 图论 + 并查集 )

    题目链接 解题报告: 思路:如果将一个黑色点染成白色,那么将得到一个白色连通块,这个连通块由和这个黑色点连结的所有白色连通块组成. 如果将一个白色点染成白色,那么不会有任何变化. 所以我们可以先并查集 ...

  3. 证明kruskal算法求解图的最小生成树具有贪心选择性质_将并查集应用在图论中的最小生成树算法——Kruskal...

    点击上方蓝字,和我一起学技术. 今天是算法和数据结构专题的第19篇文章,我们一起来看看最小生成树. 我们先不讲算法的原理,也不讲一些七七八八的概念,因为对于初学者来说,看到这些术语和概念往往会很头疼. ...

  4. bzoj4144 [AMPPZ2014]Petrol 图论 最短路 并查集

    bzoj4144 [AMPPZ2014]Petrol 图论 最短路 并查集 1.这道题我们主要就是要求出距离一个油站的最近的油站 首先我们dijkstra 求出任意一个点到 离他最近的油站的距离 2. ...

  5. 图论:并查集求最小环

    图论:并查集求最小环 概念: 图.路.环: 一个有向图由G=(N,A)表示,其中N表示节点集,A表示边集边(i,j)为一有序对,i为出发节点,j为终止节点.在无向图中(i,j)与(j,i)一致. 路是 ...

  6. 图论8 并查集深入解析——边带权并查集和拓展域并查集和最小生成树

    我们先复习一下并查集的基本知识. 并查集的三个操作:查询,初始化,合并:并查集的结构:操作方法以及代码:路径压缩优化(详见<图论7 弗洛伊德&并查集算法详解>). 补充一下,并查集 ...

  7. 「图论」第1章 并查集课堂过关

    文章目录 A. [例题1][模板]并查集 题目 代码 B. [例题2]程序自动分析 题目 代码 C. [例题3]银河英雄传说 题目 题目背景 题目描述 输入格式 输出格式 输入输出样例 说明/提示 思 ...

  8. 图论500题 ---- 并查集求路径上最大值最小不超过K的点对数 HDU Portal

    题目链接 题目大意: 就给你一个图,qqq次询问,问你这个图上有多少对点之间的所以路径上的最大值的最小值不超过kkk? 解题思路: 首先我们知道这本质上就是求两个点联通的路径上的最大值最小是多少? 那 ...

  9. 算法提高课-图论-欧拉回路和欧拉路径-AcWing 1185. 单词游戏:判断有向图是否存在欧拉路径、并查集

    文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 把每个单词看成一条边!!!首字母到尾字母的一条边,最多共有26个点(26个小写的英文字母),然后问能否把所有边串起来. 其实,对欧拉 ...

  10. Graph Destruction 并查集,图论(500)

    题意 : 给一n个点m条边的无向图,问逐渐删去1-n点及它们的边,分别输出当前剩下多少个连通区域 思路 : 求连通块,想到了并查集,但并查集是增边,这里是减边,只要倒序考虑问题即可,那么问题转换为 : ...

最新文章

  1. python3 urllib 类
  2. web-QQ(腾讯)-Email-TMessage(腾讯微博记事本)
  3. 计算机网络【wireshark抓包分析】
  4. yum因被锁定导致无法执行相关操作的解决方法
  5. 【OpenCV 例程200篇】73. 二维连续傅里叶变换
  6. Python攻克之路-高阶函数
  7. W3C 宣布:WebAuthn 成为正式 Web 标准
  8. signalr收不到服务器的信息,重新连接的客户端SignalR没有收到消息 - javascript
  9. jQuery EasyUI 简介
  10. 粒子群算法的惩罚函数的c语言实现,粒子群算法结合惩罚函数用于桥式起重机主梁优化.pdf...
  11. Macbook OBS 录制系统声音
  12. 使用scrapy爬取dota2贴吧数据并进行分析
  13. java读写十六进制文件_Java:文件到十六进制
  14. 智能厨房监控系统设计
  15. 游戏程序常规设计模式
  16. 差分隐私 python_差分隐私
  17. mysql主从复制,互为主从与读写分离
  18. 形容人的内核是什么意思_请问甜文的内核是什么?
  19. java数据库中间件实现,分布式数据库中间件DDM的实现原理
  20. 万圣节html代码大全,方舟生存进化249万圣节新版本代码大全分享

热门文章

  1. 第二周java基础学习内容
  2. [android] 切换界面的通用处理
  3. 通过代码设置radiobutton不同方位图标的两种方法
  4. 关于网上商城开发的随笔记录2
  5. 快切-开源中文css框架之纯css透明
  6. Apache简单配置(5)搭建phpcms2007网站+phpBB-3.0论坛
  7. 在c语言Windows窗口添加按钮,C语言用windows.h创建按钮的问题
  8. Eclipse中打包maven项目-war包方式
  9. this.controls指所有控件吗?_Excel 控件【窗体控件】和【ActiveX控件】使用基础教程...
  10. Unity中脚本的生命周期