1977: [beijing2010 team up] Small Spanning Tree treetime limit: 10 sec memory limit: 512 MB
Submit: 2108 solved: 463
[Submit] [Status] Description
Mr. C recently learned many algorithms for the minimal spanning tree, such as the prim algorithm, the kurskal algorithm, and the decircle algorithm. Just as little C is proud, little P is pouring cold water on little c again. Small P said that let small C find an undirected graph of the secondary generation tree, and this small generation tree must be strictly small, that is, if the edge set selected by the minimum generation tree is em, when the edge set selected by the small generation tree is es, it must satisfy the following requirements: (value (e) indicates the weight of edge e.) now John finds you, I hope you can help him solve this problem.
Input
The first line contains two integers n and M, indicating the number of points and edges of an undirected graph. In the next m row, three numbers x y z in each row indicate that there is an edge between vertex x and vertex y, and the edge weight is Z.
Output
Contains a row and only a number, indicating the edge weight of a small tree. (Data guarantee must exist strictly for minor generation trees)
Sample input5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6 sample output11hint
In the data, undirected graphs have no self-loops. 50% of data is n ≤ 2 000 m ≤ 3 000; 80% of data is n ≤ 50 000 m ≤ 100 000; 100% of the data is n ≤ 100 000 m ≤ 300 000, and the edge weight is not negative and cannot exceed 10 ^ 9.
Source
Question:
No more Sb... Array out-of-bounds + XY reversed...
If not strictly, you only need to enumerate each edge. On the MST, record the largest edge between the two points as X and the weight of the current enumeration edge as Y, use y-X to update the answer.
But what if it is strict? If y = x, can we ignore this edge?
Of course not. The next generation tree is obtained by adding an edge to the MST and deleting another edge.
Think about it. If the secondary attention between the two points is removed and Y is added, it may also become the answer. It won't be the third largest.
Therefore, we need to find a large edge and update the answer based on the situation.
What I do not understand is:
How many different edges can be added to different MST instances? How can we ensure that any MST can obtain the correct answer through the operations in this question?
Please kindly advise.
Code:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 100000+100 14 #define maxm 300000+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 using namespace std; 22 inline int read() 23 { 24 int x=0,f=1;char ch=getchar(); 25 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 26 while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();} 27 return x*f; 28 } 29 int dep[maxn],fa[maxn],head[maxn],tot,n,m,f[maxn][22]; 30 bool out[maxm]; 31 struct recc{int a,b;} g[maxn][22],ret; 32 struct edge{int go,next,w;}e[2*maxn]; 33 struct rec{int x,y,z;}a[maxm]; 34 inline void insert(int x,int y,int w) 35 { 36 e[++tot].go=y;e[tot].w=w;e[tot].next=head[x];head[x]=tot; 37 e[++tot].go=x;e[tot].w=w;e[tot].next=head[y];head[y]=tot; 38 } 39 inline bool cmp(rec a,rec b) 40 { 41 return a.z<b.z; 42 } 43 inline void update(recc &x,recc &y) 44 { 45 if(y.a<x.a)y.b=y.a,y.a=x.a; 46 else {if(x.a>y.b&&x.a<y.a)y.b=x.a;} 47 if(x.b==-1)return; 48 if(y.a<x.b)y.b=y.a,y.a=x.b; 49 else {if(x.b>y.b&&x.b<y.a)y.b=x.b;} 50 } 51 inline void dfs(int x) 52 { 53 for1(i,20) 54 if((1<<i)<=dep[x]) 55 { 56 f[x][i]=f[f[x][i-1]][i-1]; 57 g[x][i].a=g[x][i].b=-1; 58 update(g[f[x][i-1]][i-1],g[x][i]); 59 update(g[x][i-1],g[x][i]); 60 } 61 else break; 62 for(int i=head[x],y;i;i=e[i].next) 63 if(!dep[y=e[i].go]) 64 { 65 f[y][0]=x;g[y][0].a=e[i].w;g[y][0].b=-1; 66 dep[y]=dep[x]+1; 67 dfs(y); 68 } 69 } 70 inline void query(int x,int y) 71 { 72 if(dep[x]<dep[y])swap(x,y); 73 int t=dep[x]-dep[y]; 74 ret.a=ret.b=-1; 75 for0(i,20) 76 if(t&(1<<i)) 77 { 78 update(g[x][i],ret); 79 x=f[x][i]; 80 } 81 if(x==y)return; 82 for(int i=20;i>=0;i--) 83 if(f[x][i]!=f[y][i]) 84 { 85 86 update(g[x][i],ret);x=f[x][i]; 87 update(g[y][i],ret);y=f[y][i]; 88 } 89 update(g[x][0],ret);update(g[y][0],ret); 90 } 91 inline int find(int x) 92 { 93 return fa[x]==x?x:fa[x]=find(fa[x]); 94 } 95 int main() 96 { 97 freopen("input.txt","r",stdin); 98 freopen("output.txt","w",stdout); 99 n=read();m=read();100 for1(i,m)a[i].x=read(),a[i].y=read(),a[i].z=read();101 sort(a+1,a+m+1,cmp);102 for1(i,n)fa[i]=i;103 ll sum=0,ans=inf;104 for(int i=1,j=1;i<=n-1;i++)105 {106 while(find(a[j].x)==find(a[j].y))j++;107 fa[find(a[j].x)]=find(a[j].y);insert(a[j].x,a[j].y,a[j].z);108 out[j]=1;109 sum+=a[j].z;j++;110 }111 dep[1]=1;g[1][0].a=g[1][0].b=-1;112 dfs(1);113 for1(i,m)if(!out[i])114 {115 int x=a[i].x,y=a[i].y,z=a[i].z;query(x,y);116 if(ret.a!=z&&z-ret.a<ans)ans=z-ret.a;117 if(ret.a==z&&ret.b!=-1&&z-ret.b<ans)ans=z-ret.b;118 }119 printf("%lld\n",ans+sum);120 return 0;121 }View code
Bzoj1977: [beijing2010 team up] generation tree