[JZOJ5060]公路建设
来源:互联网 发布:韩顺平javascript 编辑:程序博客网 时间:2024/06/05 09:40
题目大意
一个图有
有
题目分析
显然题目是求区间内的边的最小生成森林的边权和。
可以发现最小生成树(森林)具有可合并性。
一个很显然的想法:将所有边按照编号分块,设每一块大小为
然后询问时直接拿出跨块的
不过这个方法还是太naive了,我们把分块换成线段树就可以在
代码实现
于是我依然特别naive地打了分块。
#include <algorithm>#include <iostream>#include <cstdio>#include <cctype>#include <cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}int buf[30];void write(int x){ if (x<0) putchar('-'),x=-x; for (;x;x/=10) buf[++buf[0]]=x%10; if (!buf[0]) buf[++buf[0]]=0; for (;buf[0];putchar('0'+buf[buf[0]--]));}const int N=105;const int M=100005;const int B=500;int srt[M],id[M];int fa[N],rank[N];int mst[B][B][N];int st[B],en[B];int edg[M][3];int n,m,q,cnt,bs,bcnt;int getfather(int son){return fa[son]==son?son:fa[son]=getfather(fa[son]);}void merge(int x,int y){ if (rank[x]<rank[y]) swap(x,y); fa[y]=x,rank[x]+=rank[x]==rank[y];}bool cmp(int x,int y){return edg[id[x]][2]<edg[id[y]][2];}int Kruscal(int *e){ e[0]=0; int ret=0; for (int i=1;i<=cnt;++i) srt[i]=i; sort(srt+1,srt+1+cnt,cmp); for (int i=1;i<=n;++i) fa[i]=i,rank[i]=0; for (int i=1,j,x,y;i<=cnt;++i) { j=id[srt[i]],x=getfather(edg[j][0]),y=getfather(edg[j][1]); if (x!=y) merge(x,y),ret+=edg[j][2],e[++e[0]]=j; } return ret;}void block(){ bs=trunc(sqrt(m)); for (int l=1,r;l<=m;l=r+1) { st[++bcnt]=l,en[bcnt]=r=min(m,l+bs-1),cnt=0; for (int i=l;i<=r;++i) id[++cnt]=i; Kruscal(mst[bcnt][bcnt]); } for (int i=1;i<bcnt;++i) for (int j=i+1;j<=bcnt;++j) { cnt=0; for (int k=1;k<=mst[i][j-1][0];++k) id[++cnt]=mst[i][j-1][k]; for (int k=1;k<=mst[j][j][0];++k) id[++cnt]=mst[j][j][k]; Kruscal(mst[i][j]); }}int main(){ freopen("highway.in","r",stdin),freopen("highway.out","w",stdout); n=read(),m=read(),q=read(); for (int i=1;i<=m;++i) for (int j=0;j<3;++j) edg[i][j]=read(); block(); for (int l,r,lid,rid;q--;printf("%d\n",Kruscal(mst[0][0]))) { l=read(),r=read(),lid=rid=0,cnt=0; for (int i=1;i<=bcnt;++i) { if (en[i]<l) continue; if (st[i]>r) break; if (st[i]<=l) for (int j=l;j<=en[i]&&j<=r;++j) id[++cnt]=j; else if (en[i]>=r) for (int j=st[i];j<=r;++j) id[++cnt]=j; else { if (!lid) lid=i; rid=i; } } if (lid) for (int i=1;i<=mst[lid][rid][0];++i) id[++cnt]=mst[lid][rid][i]; } fclose(stdin),fclose(stdout); return 0;}
0 0
- [JZOJ5060]公路建设
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设
- 【jzoj5060】【GDOI2017第二轮模拟day1】【公路建设】【数据结构】
- 5060. 公路建设
- 【公路建设】解题报告
- 【GDOI2017第二轮模拟day1】公路建设
- 【Kruskal】公路建设(Road.exe, 1s, 64M)
- jzoj 5060. 【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树
- 【GDOI2017第二轮模拟day1】公路建设(克鲁斯卡尔最小生成树+线段树+归并)
- struts2基础学习收录重点之OGNL动态配置result , 使用注解配置action,实现java国际化
- 支付宝支付之从前台打通到后台(二)
- java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting ‘name pattern’
- dp---跳跃游戏
- vim配置
- [JZOJ5060]公路建设
- QComboBox下拉框 + 颜色相关
- 无等待地从一个消息队列中取得消息, OSQAccept()
- the diary for one command application of pipe in Linux
- C++:类和对象
- OpenCV I_3图片基础
- Serializable java序列化
- HDU 2732&&POJ 2711 Leapin' Lizards 【最大流Dinic】
- 10年