题目链接:

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. git 入门二 (基础)

     1.创建新仓库      git init    touch  test.txt  git add --a  git commit -m "fist commit"    初始化 ...

  2. 卸载系统自带libevent

    rpm -qa|grep libevent yum remove libevent* 或 rpm -e --nodeps --allmatches libevent*

  3. -[ASIDataCompressor compressBytes:length:error:shouldFinish:] in ASIDataCompressor.o

    本文转载至 http://blog.csdn.net/m372897500/article/details/38293973 -[ASIDataCompressor compressBytes:len ...

  4. Android 新建一个类,在src新建一个类,使继承自活动

    一:先新建一个包 右键src,新建包: 二:包中新建类 右建包,新建类,将超类改为andorid.app.Activity

  5. Intersection(计算几何)

    Intersection Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)To ...

  6. cocos2dx使用cocostudio导出的animation

    local uilocal function createLayerUI() if not ui then ui=cc.Layer:create(); createLayerUI=nil; end r ...

  7. Android系统移植与调试之------->如何修改Android设备的默认休眠时间

    1.找到~/mx0831-0525/frameworks/base/packages/SettingsProvider/res/values/ defaults.xml文件 2.修改默认休眠时间 3. ...

  8. C#练习DataReader

    SQL代码: create database ThreeDb go USE ThreeDb; GO CREATE TABLE classify --分类表 ( id ,), name ) not nu ...

  9. vim中使用sed去除网上copy的源代码行号和空格

    有些时候,在网上搜索到的代码都包含有行号,高亮显示控件不支持直接提取,如: test.sh 01 #!/bin/bash 02 echo “aaa” 简单的去掉行号和前面的空格: 方案一: 1.vim ...

  10. Git——基本思想和工作原理(二)

    核心知识点: 1.Git关注文件数据的整体是否发生变化,对更新的文件做一个快照,然后保存一个指向快照的索引,而不会关注文件数据的具体变化. 2.Git版本的更新几乎都发生在本地,不会因为没有网络而不能 ...