题意

在一个有N(1 ≤ N ≤ 1,000)个点环形图上有P(1 ≤ P ≤ 10,000)对点需要连接。连接只能连接环上相邻的点。问至少需要连接几条边。

思路

突破点在于最后的结果一定不是一个环!所以我们枚举断边,则对于P个连接要求都只有唯一的方法:如果一个pair的两个端点在断点两侧,就分成[0,left],[right,N];否则就是[left, right]。这里区间以0开头是要考虑left=1、right=N的情况,至少得有个边([0, 1])表示N连向1的情况不是么。 处理一个区间内相连情况通常可以用线段树。不过我在这里用了下并查集,也挺有意思的:每个并查集的父节点是它连接着的最右端的节点,并且维护一个数量集。然后连接[x, y]的时候直接找x的父节点(最右点),再挨个向右缩点直到y即可。

代码

[cpp] #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #define MID(x,y) ((x+y)/2) #define MEM(a,b) memset(a,b,sizeof(a)) #define REP(i, begin, end) for (int i = begin; i <= end; i ++) using namespace std; struct P{ int a, b; }p[10005]; const int MAXN = 1005; struct Disjoint_Sets{ struct Sets{ int father, num; }S[MAXN]; void Init(int n){ for (int i = 0; i <= n; i ++){ S[i].father = i; S[i].num = 1; } } int Father(int x){ if (S[x].father == x){ return x; } else{ S[x].father = Father(S[x].father); //Path compression return S[x].father; } } void Union(int x, int y){ int fx = Father(x), fy = Father(y); S[fy].num += S[fx].num; S[fx].father = fy; } }DS; void uni(int x, int y){ int xx = DS.Father(x); while(DS.Father(xx) != DS.Father(y)){ DS.Union(xx, xx+1); xx = DS.Father(xx); } } int main(){ //freopen("test.in", "r", stdin); //freopen("test.out", "w", stdout); int n, m; scanf("%d %d", &n, &m); for (int i = 0; i < m; i ++){ scanf("%d %d", &p[i].a, &p[i].b); if (p[i].b < p[i].a) swap(p[i].b, p[i].a); } int res = 0x3fffffff; for (int l = 1; l <= n; l ++){ DS.Init(n); for (int i = 0; i < m; i ++){ if (p[i].a <= l && p[i].b >= (l+1)%n){ uni(0, p[i].a); uni(p[i].b, n); } else uni(p[i].a, p[i].b); } int sum = 0; bool vis[1005] = {0}; for (int i = 1; i <= n; i ++){ if (!vis[DS.Father(i)] && DS.S[DS.Father(i)].num > 1){ sum += DS.S[DS.Father(i)].num - 1; vis[DS.Father(i)] = 1; } } res = min(res, sum); } printf("%d\n", res); return 0; } [/cpp]

转载于:https://www.cnblogs.com/AbandonZHANG/p/4114139.html

POJ 1944 Fiber Communications (枚举 + 并查集 OR 线段树)相关推荐

  1. POJ 1944 - Fiber Communications

    原题地址:http://poj.org/problem?id=1944 题目大意:有n个点排成一圈,可以连接任意两个相邻的点,给出 p 对点,要求这 p 对点必须直接或间接相连,求最少的连接边数 数据 ...

  2. Gym - 101194G Pandaria (并查集+倍增+线段树合并)

    题意: 给定一个无向图.每个点有一种颜色.现在给定q个询问,每次询问x和w,求所有能通过边权值不超过w的边走到x的点的集合中,哪一种颜色的点出现的次数最多.次数相同时输出编号最小的那个颜色.强制在线. ...

  3. 【HDU - 4056】Draw a Mess (并查集 or 线段树)

    题干: It's graduated season, every students should leave something on the wall, so....they draw a lot ...

  4. 分门别类刷leetcode——高级数据结构(字典树,前缀树,trie树,并查集,线段树)

    目录 Trie树(字典树.前缀树)的基础知识 字典树的节点表示 字典树构造的例子 字典树的前序遍历 获取字典树中全部单词 字典树的整体功能 字典树的插入操作 字典树的搜索操作 字典树的前缀查询 字典树 ...

  5. poj 1456 Supermarket (贪心, 并查集)

    链接: http://poj.org/problem?id=1456 题目: Description A supermarket has a set Prod of products on sale. ...

  6. BZOJ 1050: [HAOI2006]旅行comf(枚举+并查集)

    [HAOI2006]旅行comf Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点 ...

  7. POJ 2236 Wireless Network (并查集)

    Wireless Network 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/A Description An earthqu ...

  8. hdu1589(枚举+并查集)

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  9. 食物链 POJ - 1182(带权并查集模板)

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种 ...

最新文章

  1. active set + serving cell
  2. stopping NetworkManager daemon failed
  3. PHP与base64
  4. python获取当前服务器ip_Python实现获取域名所用服务器的真实IP
  5. java Gregorian,Java GregorianCalendar getTimeZone()用法及代码示例
  6. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1039:判断数正负
  7. 【学习笔记】数据链路层——流量控制:停止等待协议、后退N帧协议(GBN)、选择重传协议(SR)
  8. 测试驱动开发_DevOps之浅谈测试驱动开发
  9. tensorflow第十一步CNN表情识别
  10. BP神经网络的MATLAB实现
  11. Confluence或JIRA验证码乱码的问题
  12. mysql 联合表(federated)及视图
  13. 英制BSW 美制UNC 螺牙的理解
  14. oracle 范鑫_自己写得一个类似AUL的工具,附源代码(C 语言)
  15. thinkphp系列
  16. redis学习日志 【一、安装】
  17. 物联网系统中常见的通信协议分析
  18. 战舰STM32控制L9110电机驱动
  19. 利用Github Actions部署自动更新PaddleOCR指定代码到指定仓库
  20. 人生总在不断的折腾,你不折腾,就要被折腾......

热门文章

  1. 微信利用PHP创建自定义菜单的方法
  2. linux中常用的头文件
  3. mysql事务实战_mysql事务隔离级别详解和实战
  4. jedis使用_Redis的三个框架:Jedis,Redisson,Lettuce
  5. linux进程间的通信(C): 共享内存
  6. android IO流_Flutter实战经验(十):打包和发布到 Android 平台
  7. 小心DLL链接静态库时的内存错误
  8. MATLAB figure中提取数据
  9. c语言float m1 m2什么意思,m1和m2的区别,一文带你秒懂这两者的关联
  10. 域名如何设置才能带www和不带www都能正常访问