题目链接:

Road

Time Limit: 12000/6000 MS (Java/Others)   

 Memory Limit: 65536/65536 K (Java/Others)

Problem Description
There are n villages along a high way, and divided the high way into n-1 segments. Each segment would charge a certain amount of money for being open for one day, and you can open or close an arbitrary segment in an arbitrary day, but you can open or close the segment for just one time, because the workers would be angry if you told them to work multiple period.

We know the transport plan in the next m days, each day there is one cargo need to transport from village ai to village bi, and you need to guarantee that the segments between ai and bi are open in the i-th day. Your boss wants to minimize the total cost of the next m days, and you need to tell him the charge for each day.

(At the beginning, all the segments are closed.)

 
Input
Multiple test case. For each test case, begins with two integers n, m(1<=n,m<=200000), next line contains n-1 integers. The i-th integer wi(1<=wi<=1000) indicates the charge for the segment between village i and village i+1 being open for one day. Next m lines, each line contains two integers ai,bi(1≤ai,bi<=n,ai!=bi).
 
Output
For each test case, output m lines, each line contains the charge for the i-th day.
 
Sample Input
4 3
1 2 3
1 3
3 4
2 4
 
Sample Output
3
5
5
 
题意:
 
问那个点中间n-1个线段,每个线段只能开关一次,m天,每天要从ai到bi,要求这中间的线段都是开着的;现在问每天的最少花费是多少;
 
思路:
 
可以发现,每个线段在它第一次和最后一次被覆盖这期间都需要打开;所以需要找到每个线段的开始和结束时间
用并查集p[i]表示[i,~的第一个还没有被覆盖的位置;然后1~m和m~1个扫一遍可以找到开始和结束时间;
然后对于第i天,先加上这一天需要打开的线段,和就是这天的答案,然后再减去这一天需要关闭的线段;
 
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=2e5+20;
const int maxn=1e4+220;
const double eps=1e-12; int n,m,w[N],a[N],b[N],p[N];
int x,y;
vector<int>st[N],en[N];
int findset(int x)
{
if(x==p[x])return x;
return p[x]=findset(p[x]);
}
int same(int x,int y)
{
int fx=findset(x),fy=findset(y);
if(fx>fy)p[fy]=fx;
else if(fx<fy)p[fx]=fy;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
For(i,1,n-1)read(w[i]);
int high=max(n,m)+10;
for(int i=0;i<=high;i++)
{
p[i]=i;
st[i].clear();
en[i].clear();
}
For(i,1,m)
{
read(a[i]);read(b[i]);
if(a[i]>b[i])swap(a[i],b[i]);
int r=a[i];
while(1)
{
r=findset(r);
if(r>=b[i])break;
same(r,r+1);
st[i].push_back(r);
}
}
for(int i=0;i<=high;i++)p[i]=i;
for(int i=m;i>0;i--)//找到第i天要关闭的线段
{
int r=a[i];
while(1)
{
r=findset(r);
if(r>=b[i])break;
same(r,r+1);
en[i].push_back(r);
}
}
int ans=0;
for(int i=1;i<=m;i++)
{
int len=st[i].size();
for(int j=0;j<len;j++)//加上这一天要打开的线段
{
int x=st[i][j];
ans+=w[x];
}
print(ans);
len=en[i].size();
for(int j=0;j<len;j++)//关闭这天需要关闭的线段;
{
int x=en[i][j];
ans-=w[x];
}
}
}
return 0;
}

  

hdu-5861 Road(并查集)的更多相关文章

  1. hdu 5861 Road 两棵线段树

    传送门:hdu 5861 Road 题意: 水平线上n个村子间有 n-1 条路. 每条路开放一天的价格为 Wi 有 m 天的操作,每天需要用到村子 Ai~Bi 间的道路 每条路只能开放或关闭一次. ( ...

  2. HDU 1598 find the most comfortable road 并查集+贪心

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1598 find the most comfortable road Time Limit: 1000 ...

  3. hdu 1598 find the most comfortable road (并查集)

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

  4. HDU 2818 (矢量并查集)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2818 题目大意:每次指定一块砖头,移动砖头所在堆到另一堆.查询指定砖头下面有几块砖头. 解题思路: ...

  5. hdu 1116 欧拉回路+并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=1116 给你一些英文单词,判断所有单词能不能连成一串,类似成语接龙的意思.但是如果有多个重复的单词时,也必须满足这 ...

  6. Bipartite Graph hdu 5313 bitset 并查集 二分图

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5313 题意: 给出n个顶点,m条边,问最多添加多少条边使之构成一个完全二分图 存储结构: bitset   ...

  7. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

  8. hdu 3081(二分+并查集+最大流||二分图匹配)

    Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. 2015 ACM/ICPC Asia Regional Changchun Online HDU - 5441 (离线+并查集)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给你n,m,k,代表n个城市,m条边,k次查询,每次查询输入一个x,然后让你一个城市对(u,v ...

随机推荐

  1. 【转】使用Python学习selenium测试工具

    出处:https://my.oschina.net/u/1433482/blog/633231?fromerr=vaxqh9bn

  2. 零基础学python-2.7 列表与元组

    事实上,能够把列表和元组看成普通的数组.可是这个数组能够存储不同的数据类型(对象) 列表和元组的差别   列表 元组 使用的符号 [] () 元素数量 可变 不可变 改动元素 不能够 能够 假设大家有 ...

  3. 并发检测主机ip存活脚本

    #!/bin/bash ################### # Check Active Host####### ################### function CheckInput() ...

  4. Node-Webkit - package.json - 参数设置

    必填: main :(string)APP的主入口,指定一个html文件,如:main:"index.htm". name :(string)APP的名称,必须具有唯一性. 例子: ...

  5. app 之间发送文件 ios

    本文转载至 http://www.51094.com/?p=212   第一种: 发送一个正常的  pdf 文件,只要是能读取pdf 的都能得到响应 -(IBAction)openDocumentIn ...

  6. lua注册函数

    #include <stdio.h> #include <math.h> #define MAX_COLOR 255 extern "C" { #inclu ...

  7. codevs 必做:2776、1222

    2776 寻找代表元  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 广州二中苏元实验学校一共有n个社团,分 ...

  8. 还原sqlserver2008 r2 数据库步骤

    1: 有备份文件bak 文件(是在sqlserver2008 r2上备份的) 数据库下载地址(讯雷) ed2k://|file|cn_sql_server_2008_r2_express_with_m ...

  9. delete 和 truncate 的 区别

    如果要清空表中的所有记录,可以使用下面的两种方法: DELETE FROM table1     TRUNCATE TABLE table1 以下 为之区别: 1)执行速度和灵活性    trunca ...

  10. shell if判断-n

    test测试命令 test命令用于检查某个条件是否成立,它可以进行数值.字符串和文件三个方面的测试,其测试符和相应的功能分别如下: (1)数值测试: -eq:等于则为真        -ne:不等于则 ...