八中生成树2 【最小生成树】

本人水平有限,题解不到为处,请多多谅解

 

本蒟蒻谢谢大家观看

参考博客传送门 

扫描二维码关注公众号,回复: 7708524 查看本文章

题目:

1639: 八中生成树2

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 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元后,是否可以得到一个比从前总开支相等或更小的方案

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\n");
79         }
80         else{
81             printf("No\n");
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 */

猜你喜欢

转载自www.cnblogs.com/nlyzl/p/11776228.html