2、公路建设(highway.c/cpp/pas)

在滨海市一共有n 个城市,编号依次为1到n,它们之间计划修建m条双向道路,其中修建第i条道路的费用为ci。

海霸王作为滨海市公路建设项目的总工程师,他决定选定一个区间[l,r],仅使用编号在该区间内的道路。他希望选择一些道路去修建,使得连通块的个数尽量少,同时,他不喜欢修建多余的道路,因此每个连通块都可以看成一棵树的结构。为了选出最佳的区间,海霸王会不断选择q个区间,请写一个程序,帮助海霸王计算每个区间内修建公路的最小总费用。

Input

第一行包含三个正整数n,m,q,表示城市数、道路数和询问数。接下来m行,每行三个正整数ui,vi,ci,表示一条连接城市ui和vi的双向道路,费用为ci。接下来q行,每行两个正整数li,ri,表示一个询问。

Output输出q行,每行一个整数,即最小总费用。

Notes

60% 从ci=i。

100% 的数据,1 ≤ui,vi≤n<=100,ui≠vi,1≤li≤ri≤m,1≤ci≤106。

【题解】

考虑部分分,边的权值单调递增。

直接倒着扫所有边,加入该边时如果还未连通就直接加,否则找到环上最大的边删去换成这条,将查询按左端点从大到小排序,扫到左端点相同时查询现在树上所有边是否在区间内,是就将答案加它。

正解

发现n很小,可以使用线段树,叶子结点表示每条路,区间查询[l,r]即可。

每个节点维护一个vector表示这个区间内生成的最小生成森林选了那些边。

合并时使用归并排序,将2个区间的边排序后跑克鲁斯卡尔即可。

复杂度m*n+q*logm*n。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+;
int n,m,q,fa[],b[M];
struct bian
{
int u,v,c,id;
}a[M];
vector <int> ve[M<<],ddhu,ans;
inline int find(int x)
{
if(x==fa[x]) return x;
fa[x]=find(fa[x]);
return fa[x];
}
inline int read()
{
char c=getchar();
int x=,f=;
while(!isdigit(c)) {if(c=='-') f=-;c=getchar();}
while(isdigit(c)) {x=(x<<)+(x<<)+c-'';c=getchar();}
return x*f;
}
inline void pushup(int x,int y)
{
ddhu.clear();
int cnt=,zi=,yi=,zlen=ve[x].size(),ylen=ve[y].size();
while(zi<zlen&&yi<ylen)
{
if(a[ve[x][zi]].c<a[ve[y][yi]].c) b[++cnt]=ve[x][zi++];
else b[++cnt]=ve[y][yi++];
}
while(zi<zlen) b[++cnt]=ve[x][zi++];
while(yi<ylen) b[++cnt]=ve[y][yi++];
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=cnt;i++)
{
int fa1=find(a[b[i]].u);
int fa2=find(a[b[i]].v);
if(fa1!=fa2)
{
fa[fa1]=fa2;
ddhu.push_back(b[i]);
}
}
} inline void build(int now,int l,int r)
{
if(l==r)
{
ve[now].push_back(l);
return;
}
int mid=(l+r)>>;
build(now<<,l,mid);
build(now<<|,mid+,r);
pushup(now<<,now<<|);
ve[now].clear();
int gu=ddhu.size();
for(int i=;i<gu;i++) ve[now].push_back(ddhu[i]);
}
inline void query(int now,int l,int r,int L,int R)
{
if(l>=L&&r<=R)
{
int huan=ans.size();
ve[(M<<)-].clear();
for(int i=;i<huan;i++) ve[(M<<)-].push_back(ans[i]);
pushup((M<<)-,now);huan=ddhu.size();ans.clear();
for(int i=;i<huan;i++) ans.push_back(ddhu[i]);
return;
}
int mid=(l+r)>>;
if(L<=mid) query(now<<,l,mid,L,R);
if(R>=mid+) query(now<<|,mid+,r,L,R);
}
int main()
{
// freopen("highway.in","r",stdin);
// freopen("highway.out","w",stdout);
n=read();m=read();q=read();
for(int i=;i<=m;i++)
a[i].u=read(),a[i].v=read(),a[i].c=read();
build(,,m);
for(int i=,x,y;i<=q;i++)
{
x=read();y=read();
ans.clear();
query(,,m,x,y);
int daan=,huan=ans.size();
for(int j=;j<huan;j++) daan+=a[ans[j]].c;
cout<<daan<<"\n";
}
fclose(stdin);
fclose(stdout);
} //3 5 2
//1 3 2
//2 3 1
//2 1 6
//3 1 7
//2 3 7
//2 5
//3 4

floj 2264的更多相关文章

  1. [COGS 2264]魔法传输

    [COGS 2264]魔法传输 题目 自从看了<哈利波特>,小Y就十分渴望获得魔法值.于是他和一群向往魔法的孩子(当然这些孩子们都是不会魔法的)来到了哈利波特的家,大家坐成一排.哈利波特会 ...

  2. LCS(打印全路径) POJ 2264 Advanced Fruits

    题目传送门 题意:两个字符串结合起来,公共的字符只输出一次 分析:LCS,记录每个字符的路径 代码: /* LCS(记录路径)模板题: 用递归打印路径:) */ #include <cstdio ...

  3. 【LOJ】#2264. 「CTSC2017」吉夫特

    题解 根据一番认真严肃的猜结论和打表证明之后 我们可以得到 \(f[i] = (\sum_{a[i] \& a[j] == a[j]} f[j]) + 1\) 统计所有的\(f[i] - 1\ ...

  4. poj 2264(LCS)

    Advanced Fruits Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2158   Accepted: 1066   ...

  5. poj 2264 Advanced Fruits(DP)

    Advanced Fruits Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1944   Accepted: 967   ...

  6. floj 2265 【lxs Contest #141】航海舰队

    首先抠出包围了阵形的最小矩形. 将地图拉伸成一条链,即将第一行.第二行.第三行按顺序连接.阵形也可以用同样的方法处理. 那么问题转化为,给定两个 01 串 S 和 T,问每个 S 中长度为 |T| 的 ...

  7. (转) [it-ebooks]电子书列表

    [it-ebooks]电子书列表   [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Obj ...

  8. 【BZOJ-3143】游走 高斯消元 + 概率期望

    3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2264  Solved: 987[Submit][Status] ...

  9. poj上的dp专题

    更新中... http://poj.org/problem?id=1037 dp[i][j][0]表示序列长度为i,以j开始并且前两位下降的合法序列数目; dp[i][j][1]表示序列长度为i, 以 ...

随机推荐

  1. H5 移动端获取当前位置

    3种方法:1.H5自带的方法,获取经纬度2.通过地图提供的JS.获取位置3.通过微信的API(这个需要公众号 / 小程序) 1.通过H5自带的获取经纬度的方法 优点: 需要引用的资源较少,H5自带的方 ...

  2. H5 FileReader读取文件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. C# “不支持给定路径的格式”异常处理

    问题背景 无聊研究了一下怎么发送邮件(包含附件),但发现附带的文件路径除了报错就是报错,不知道为什么. 用了不下好几种方式,比如 var x = "E:\\Git\\cmd\\git.exe ...

  4. P1011 圆柱体的表面积

    题目描述 输入底面半径 \(r\) 和高 \(h\) ,输出圆柱体的表面积,保留 \(3\) 位小数. 输入格式 输入包含两个实数 \(r,h(1 \le r,h \le 1000)\) 且保证输入的 ...

  5. element ui 批量删除

    <el-table :data="tableData" stripe border style="width: 100%" @selection-chan ...

  6. Python的优缺点、以及解释器种类

    优点 Python起始定位“优雅”.“明确”.“简洁”,工具型语言,上手快,实用性强. 开发效率高,支持库强大,很多功能都有与之对应的最优模块支持. 高级语言,编程时无需考虑内存等底层具体实现. 可移 ...

  7. 023.MFC_属性页控件(tab control)

    属性页控件属性页->选项卡->对话框CTabCtrl一.建立名为tabCtrl的mfc工程,添加Tab Control控件,设置属性ID为IDC_TAB,并添加变量m_tab 在tabCt ...

  8. 修改Samba密码后无法登录

    Samba修改用户名密码后,无法登陆 之后每次进去都是以这样的username和passwd进去的,如何才能使用其他的用户来重新登录samba server呢? 首先使用在开始菜单里面输入cmd: 进 ...

  9. echarts拓扑图(graph,力导向布局图)

    echarts连接:https://gallery.echartsjs.com/editor.html?c=xCLEj67T3H 讲解:https://www.cnblogs.com/koala201 ...

  10. 赋值、关系、逻辑运算、if、switch case

    cout << boolalpha将打印输出0转为false,1转为true 逻辑运算符: &&(与)    且      两个条件为真时结果为真 ||(或) 或   两个 ...