日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树

發(fā)布時間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?[Lydsy2017省隊十連測]公路建設(shè)

Time Limit:?20 Sec??Memory Limit:?512 MB
Submit:?93??Solved:?53
[Submit][Status][Discuss]

Description

在Byteland一共有n個城市,編號依次為1到n,它們之間計劃修建m條雙向道路,其中修建第i條道路的費用為ci。B yteasar作為Byteland公路建設(shè)項目的總工程師,他決定選定一個區(qū)間[l,r],僅使用編號在該區(qū)間內(nèi)的道路。他希 望選擇一些道路去修建,使得連通塊的個數(shù)盡量少,同時,他不喜歡修建多余的道路,因此每個連通塊都可以看成 一棵樹的結(jié)構(gòu)。為了選出最佳的區(qū)間, Byteasar會不斷選擇 q個區(qū)間,請寫一個程序,幫助 Byteasar計算每個區(qū) 間內(nèi)修建公路的最小總費用。?

Input

第一行包含三個正整數(shù)n; m; q,表示城市數(shù)、道路數(shù)和詢問數(shù)。 接下來m 行,每行三個正整數(shù)ui; vi; ci,表示一條連接城市ui 和vi 的雙向道路,費用為ci。 接下來q 行,每行兩個正整數(shù)li; ri,表示一個詢問。 1 ≤ ui, vi ≤ n, ui ?= vi, 1 ≤ li ≤ ri ≤ m, 1 ≤ ci ≤ 10^6 N<=100,M<=100000,Q<=15000

Output

輸出q 行,每行一個整數(shù),即最小總費用。

Sample Input

3 5 2
1 3 2
2 3 1
2 1 6
3 1 7
2 3 7
2 5
3 4

Sample Output

7
13

HINT

題解:因為點數(shù)極少所以有用的邊只有n-1條,因為最小生成樹,    所以線段樹每個節(jié)點維護的邊只需要有用的那幾條就可以了。 1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 #include<cmath> 6 7 #define N 107 8 #define M 100007 9 #define ls p<<1 10 #define rs p<<1|1 11 using namespace std; 12 inline int read() 13 { 14 int x=0,f=1;char ch=getchar(); 15 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 16 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 20 int n,m,q; 21 int fz[M],fa[N]; 22 struct Data 23 { 24 int x,y,z; 25 }a[M]; 26 struct Node 27 { 28 int sum,a[N]; 29 void init() 30 { 31 sum=0; 32 memset(a,0,sizeof(a)); 33 } 34 }tr[M<<2],ans; 35 36 int find(int x) 37 { 38 if (fa[x]!=x) fa[x]=find(fa[x]); 39 return fa[x]; 40 } 41 Node merge(Node y,Node z) 42 { 43 Node x;x.init(); 44 int i=1,j=1,k=0,op=0; 45 while(a[y.a[i]].z&&a[z.a[j]].z) 46 if (a[y.a[i]].z<a[z.a[j]].z) fz[++k]=y.a[i++]; 47 else fz[++k]=z.a[j++]; 48 while(a[y.a[i]].z) fz[++k]=y.a[i++]; 49 while(a[z.a[j]].z) fz[++k]=z.a[j++]; 50 for (int i=1;i<=n;i++) fa[i]=i; 51 for (int i=1;i<=k;i++) 52 { 53 int u=find(a[fz[i]].x),v=find(a[fz[i]].y); 54 if (u!=v) 55 { 56 fa[u]=v; 57 x.sum+=a[fz[i]].z,x.a[++op]=fz[i]; 58 } 59 } 60 return x; 61 } 62 void build(int p,int l,int r) 63 { 64 if (l==r) 65 { 66 tr[p].sum=a[l].z; 67 tr[p].a[1]=l; 68 return; 69 } 70 int mid=(l+r)>>1; 71 build(ls,l,mid),build(rs,mid+1,r); 72 tr[p]=merge(tr[ls],tr[rs]); 73 } 74 Node tree_find(int p,int l,int r,int x,int y) 75 { 76 if (l==x&&r==y) return tr[p]; 77 int mid=(l+r)>>1; 78 if (y<=mid) return tree_find(ls,l,mid,x,y); 79 else if (x>mid) return tree_find(rs,mid+1,r,x,y); 80 else return merge(tree_find(ls,l,mid,x,mid),tree_find(rs,mid+1,r,mid+1,y)); 81 } 82 int main() 83 { 84 n=read(),m=read(),q=read(); 85 for (int i=1;i<=m;i++) 86 a[i].x=read(),a[i].y=read(),a[i].z=read(); 87 build(1,1,m); 88 while(q--) 89 { 90 int l=read(),r=read(); 91 ans=tree_find(1,1,m,l,r); 92 printf("%d\n",ans.sum); 93 } 94 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/fengzhiyuan/p/8848369.html

總結(jié)

以上是生活随笔為你收集整理的bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。