题意

在一个有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进程编程

    多进程multiprocess模块 multiprocessing is a package that supports spawning processes using an API similar ...

  2. log4j 根据类名指定文件

    log4j.logger.io.netty=INFO, stdout, spiderlog4j.logger.com.ld.net.spider=INFO, stdout, spider log4j. ...

  3. Starting MySQL...The server quit without updating PID file [失败]local/mysql/data/localhost.localdomain.pid报错

    在添加命令自动补全的时候mysql启动失败 这是原配 # For advice on how to change settings please see # http://dev.mysql.com/ ...

  4. ThinkPHP5跨控制器调用

    1.在application\index\controller\文件夹里新建User.php <?php namespace app\index\controller; class User{ ...

  5. msf辅助模块的应用——20145301

    msf辅助模块的应用 实验步骤 创建msf所需的数据库 service postgresql start msfdb start 开启msf,输入命令 use auxiliary/scanner/di ...

  6. MIME协议(详解范例)

    转载一:http://blog.csdn.net/bripengandre/article/details/2192982 转载二:http://blog.csdn.net/flfna/article ...

  7. Python数据分析入门之pandas基础总结

    Pandas--"大熊猫"基础 Series Series: pandas的长枪(数据表中的一列或一行,观测向量,一维数组...) Series1 = pd.Series(np.r ...

  8. 浅入浅出JS中的eval及json

    声明: 首先声明一下,本人是JS新手,所以不敢说深入,只是把最近对eval的学习经验拿出来跟大家分享,如果您是高手可略去不看. 适合读者: 对JS中的eval一知半解,不知eval是如何把字符串转换为 ...

  9. HDU 1796 How many integers can you find(容斥)题解

    思路:二进制解决容斥问题,就和昨天做的差不多.但是这里题目给的因子不是质因子,所以我们求多个因子相乘时要算最小公倍数.题目所给的因数为非负数,故可能有0,如果因子为0就要删除. 代码: #includ ...

  10. require的shim解释

    通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim,shim解释起来也比较难理解,shim直 ...