八中生成树2 最小生成树
Posted nlyzl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八中生成树2 最小生成树相关的知识,希望对你有一定的参考价值。
本人水平有限,题解不到为处,请多多谅解
本蒟蒻谢谢大家观看
参考博客:传送门
题目:
1639: 八中生成树2
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 170 Solved: 78
[Submit][Status][Web Board]
Description
八中里面有N个建设物,M条边。
对于这种要建最小生成树的问题,你应该很熟练了。
现在老大决定降低某条边的费用,然后这条边必须要被选中,因为这条路他每天都要走,自然......
问选了这条边后是否可以得到一个比从前总开支相等或更小的方案。
对于这种要建最小生成树的问题,你应该很熟练了。
现在老大决定降低某条边的费用,然后这条边必须要被选中,因为这条路他每天都要走,自然......
问选了这条边后是否可以得到一个比从前总开支相等或更小的方案。
Input
第一行三个整数N,M,Q(1<=N<=1000,N-1<=M<=100000
接下来M行,每行三个整数(X,Y,Z)描述一条可以建造的路。 0<=Z<=10000
最后Q行,每行两个整数i,x(1<=i<=M,0<=x)描述一个修改计划,
即要你判断如果 将第i条公路的修建费用降低为x元后,是否可以得到一个比从前总开支相等或更小的方案
接下来M行,每行三个整数(X,Y,Z)描述一条可以建造的路。 0<=Z<=10000
最后Q行,每行两个整数i,x(1<=i<=M,0<=x)描述一个修改计划,
即要你判断如果 将第i条公路的修建费用降低为x元后,是否可以得到一个比从前总开支相等或更小的方案
Output
按顺序输出Q行,每行输出"Yes"或"No",Yes表示可以建造,No表示不可能
Sample Input
3 4 3
1 2 10
1 3 6
2 3 4
1 3 7
4 6
1 7
1 5
Sample Output
Yes
No
Yes
HINT
我们先可以用prim算法构造最小生成树,因为题目要求必须走它给的边,我们就可以也把这条边存储,然后由这一个点延伸。当我们求出这一条边所对应的点的最大值,与它所给的降价比较,若比其还小,则肯定为NO
code:
1 #include<bits/stdc++.h> 2 #define max(a,b) ((a)>(b)?(a):(b)) 3 #define min(a,b) ((a)<(b)?(a):(b)) 4 const int N=1e5+10; 5 const int INF=0x3f3f3f3f; 6 int n,m,k; 7 int f[1011][1011],mx[1011][1011]; 8 int pre[N],dis[N],flag[N]; 9 int e=1; 10 void inint(){ 11 freopen("tree.in","r",stdin); 12 freopen("tree.out","w",stdout); 13 } 14 inline int read(){ 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} 17 while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 18 return x*f; 19 } 20 struct oo{ 21 int u,v,w; 22 } a[N*100]; 23 void prim(){ 24 memset(flag,0,sizeof(flag)); 25 int now=1; 26 for(int i=1; i<=n; i++){ 27 dis[i]=f[1][i]; 28 } 29 dis[1]=0; 30 flag[1]=1; 31 pre[1]=1; 32 for(int i=1; i<=n; i++) { 33 int minn=INF; 34 for(int j=1; j<=n; j++){ 35 if(!flag[j]&&dis[j]<minn){ 36 minn=dis[j]; 37 now=j; 38 } 39 } 40 for(int j=1; j<=n; j++){ 41 if(flag[j]){ 42 mx[now][j]=max(mx[j][pre[now]],dis[now]); 43 mx[j][now]=mx[now][j]; 44 } 45 } 46 flag[now]=1; 47 for(int j=1; j<=n; j++){ 48 if(!flag[j]&&dis[j]>f[now][j]){ 49 dis[j]=f[now][j]; 50 pre[j]=now; 51 } 52 } 53 } 54 return ; 55 } 56 int main() 57 { 58 //inint(); 59 n=read(),m=read(),k=read(); 60 memset(f,63,sizeof(f)); 61 memset(mx,0,sizeof(mx)); 62 for(int i=1; i<=n; i++){ 63 f[i][i]=0; 64 } 65 for(int i=1,u,v,w;i<=m;i++){ 66 u=read(),v=read(),w=read(); 67 a[e].u=u; 68 a[e].v=v; 69 a[e].w=w; 70 e++; 71 f[u][v]=f[v][u]=min(f[u][v],w); 72 } 73 prim(); 74 int num,c; 75 while(k--){ 76 num=read(),c=read(); 77 if(mx[a[num].u][a[num].v]>=c){ 78 printf("Yes "); 79 } 80 else{ 81 printf("No "); 82 } 83 } 84 return 0; 85 } 86 /* 87 3 4 3 88 1 2 10 89 1 3 6 90 2 3 4 91 1 3 7 92 4 6 93 1 7 94 1 5 95 */
以上是关于八中生成树2 最小生成树的主要内容,如果未能解决你的问题,请参考以下文章
最小生成树matlab代码Kruskal算法,用于二维网络生成