题意

在一个有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]

POJ 1944 Fiber Communications (枚举 + 并查集 OR 线段树)的更多相关文章

  1. 【BZOJ2054】疯狂的馒头(并查集,线段树)

    [BZOJ2054]疯狂的馒头(并查集,线段树) 题面 BZOJ 然而权限题,随便找个离线题库看看题吧. 题解 线段树就是个暴力,如果数据可以构造就能卡掉,然而不能构造,要不然复杂度瓶颈成为了读入了. ...

  2. POJ 1944 - Fiber Communications

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

  3. 2019牛客第八场多校 E_Explorer 可撤销并查集(栈)+线段树

    目录 题意: 分析: @(2019牛客暑期多校训练营(第八场)E_Explorer) 题意: 链接 题目类似:CF366D,Gym101652T 本题给你\(n(100000)\)个点\(m(1000 ...

  4. ACM学习历程—SNNUOJ 1110 传输网络((并查集 && 离线) || (线段树 && 时间戳))(2015陕西省大学生程序设计竞赛D题)

    Description Byteland国家的网络单向传输系统可以被看成是以首都 Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的 ...

  5. HDU 3974 Assign the task 并查集/图论/线段树

    Assign the task Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  6. UVALive - 5031 Graph and Queries (并查集+平衡树/线段树)

    给定一个图,支持三种操作: 1.删除一条边 2.查询与x结点相连的第k大的结点 3.修改x结点的权值 解法:离线倒序操作,平衡树or线段树维护连通块中的所有结点信息,加个合并操作就行了. 感觉线段树要 ...

  7. poj 2236:Wireless Network(并查集,提高题)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 16065   Accepted: 677 ...

  8. POJ - 2912 Rochambeau (带权并查集+枚举)

    题意:有N个人被分为了三组,其中有一个人是开了挂的.同组的人的关系是‘=’,不同组的人关系是‘<’或'>',但是开了挂的人可以给出自己和他人任意的关系.现在要根据M条关系找出这个开了挂的人 ...

  9. poj 1182:食物链(种类并查集,食物链问题)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44168   Accepted: 12878 Description ...

随机推荐

  1. Python入门之实现简单的购物车功能

    Talk is cheap,Let's do this! product_list = [ ['Iphone7 Plus', 6500], ['Iphone8 ', 8200], ['MacBook ...

  2. Python3 解决 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

    Python3 解决 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte 一.问题 request.Reque ...

  3. 如何在 Linux 中挂载 ISO 文件

    在 Windows 中,我们常常使用 Daemon Tools 和 Virtual CloneDrive 等虚拟光驱软件挂载光盘镜像,下面我们一起来学习在 Linux 中如何挂载 ISO 文件. 在 ...

  4. 20145127《java程序设计》第九周学习总结

    一.教材学习内容总结 第十六章 整合数据库 16.1 JDBC入门 JDBC(Java DataBase Connectivity) 驱动的四种类型 JDBC-ODBC Bridge Driver N ...

  5. android 实践项目 总结 (修改)

    Android手机定位与地图实现 在一个不熟悉的环境中,获得自己的位置,选择合适的就餐地点,住宿和公交路线成为一项难题.本次的实践项目就是为了解决上述难题的,通过调用百度地图的接口实现定位.查询公交路 ...

  6. STM32唯一的ID

    请看如下程序: /*------------------------------------------------------------------------------------------ ...

  7. Windows中的时间(SYSTEMTIME和FILETIME) (转载)

    转载:http://blog.csdn.net/bokee/article/details/5330791 两种时间系统之间没有本质区别(事实上CRT时间是用Windows时间实现的,当然这是说的VC ...

  8. Hadoop MapReduce编程 API入门系列之Crime数据分析(二十五)(未完)

    不多说,直接上代码. 一共12列,我们只需提取有用的列:第二列(犯罪类型).第四列(一周的哪一天).第五列(具体时间)和第七列(犯罪场所). 思路分析 基于项目的需求,我们通过以下几步完成: 1.首先 ...

  9. 高精度N的阶乘-N!

    题目:输入一个正整数N(0<N<=30),求N! 代码: #include<stdlib.h> #include<cstdio> #include<strin ...

  10. WCF 统一处理异常利用行为服务扩展

    https://www.cnblogs.com/niaowo/p/4727378.html using System; using System.Collections.Generic; using ...