Baidu has a lot of self-study to the secondary niche into a tree after the fact is also very simple
The method of finding the minimum spanning tree is now encountering two
1 Prim record the longest segment of the line between two points F[i][k] After enumeration two points if there is no edge between two points in the smallest spanning tree then try to join it and then for the ring to remove an edge in order to achieve "sub-small" effect minus the longest, that is, the value of the is constantly updated Sub-decimal value
2 Kru records the segment that is added to the smallest spanning tree and then n-1 the enumeration every time a recorded edge is skipped Kru The resulting value is-1 or a value that may become a minor is constantly updated to determine if there are times when a small niche becomes a tree to get sub-value
POJ 1679 to find out if there is a unique minimum spanning tree in a graph in the topic of the minimum spanning tree, the approach is to see whether the same weight side has a different choice when adding the last feasible edge. If there is not the only way to use the sub-niche into a tree solution can be a small niche into a tree if the second sub-value = Minimum Not the only reverse
#include <stdio.h> #include <string.h> #include <algorithm> #include <map> #include <math.h > #include <queue> #include <iostream>using namespace std; #define MAXN 105#define MAXM 10050int DIS[MAXN]; int ta[maxn][maxn];int pre[maxn];bool use[maxn][maxn];bool vis[maxn];int f[maxn][maxn];int ans1,ans2;int n,m;int Prim ( ) {int ans=0;vis[1]=false;for (int i=1;i<=n;i++) pre[i]=1;pre[1]=-1;for (int i=2;i<=n;i++) {int minn=999999999; int p=-1; for (int k=2;k<=n;k++) {if (Vis[k]&&dis[k]<minn) {p=k; MINN=DIS[K]; }} if (minn==999999999) return-1; Vis[p]=false; ANS+=DIS[P]; Use[p][pre[p]]=use[pre[p]][p]=false; for (int k=1;k<=n;k++) {if (!vis[k]) F[p][k]=f[k][p]=max (Dis[p],f[k][pre[p]]); Dis[p] The distance from the current tree to P-point f[k][pre[p]] "K-point to the point where the P-point has been directly relaxed uli[slightly foggy] if (Vis[k]) {if (Dis[k]>ta[p][k]) {Dis[k]=ta[p][k]; Pre[k]=p; }}}} return ans;} int second () {int ans=999999999; for (int i=1;i<=n;i++) for (int k=i+1;k<=n;k++) {if (Use[i][k]) if (Ans>ans1-f[i][k]+ta[i][k]) ANS=ANS1-F[I][K]+TA[I][K]; } return ans; int main () {int t;scanf ("%d", &t), while (t--) {scanf ("%d%d", &n,&m); memset (use,false,sizeof (use)); for (int i=1;i<=n;i++) for (int k=1;k<=n;k++) ta[i][k]=999999999; for (int i=1;i<=m;i++) {int u,v,w; scanf ("%d%d%d", &u,&v,&w); Ta[u][v]=ta[v][u]=w; Use[u][v]=use[v][u]=true; } for (int i=2;i<=n;i++) dis[i]=ta[1][i]; dis[1]=0; memset (vis,true,sizeof (VIS)); memset (f,0,sizeof (F)); Ans1=prim (); Ans2=second (); if (ans1==ans2) printf ("Not unique!\n"); else printf ("%d\n", ans1);}}
HDU 4081 Test Instructions ... Qin Shihuang wants n counties to be able to reach each other and try to make the road as short as possible. He can make a road brush. No labor-intensive (the amount of manpower equals the number of counties on both sides of the road) then the two of them decided to make a compromise. B is the length of all roads except for the road A The manpower saved by the road to Xufu to maximize the value of A/b
We'll find the minimum spanning tree. If the path constructed by Xufu enumerates these path update ratios in the smallest spanning tree
What if the road is not in the construction of Xufu? The idea of a sub-niche into a tree joins the road of Xu Fu and then subtracts f[i][k] Update ratio
#include <stdio.h> #include <string.h> #include <algorithm> #include <map> #include <math.h >using namespace Std;int tot;double ans;struct node{double x,y,p;}; Node Point[1050];int n;double disz (int p1,int p2) {return sqrt ((point[p1].x-point[p2].x) * (point[p1].x-point[p2].x) + ( POINT[P1].Y-POINT[P2].Y) * (POINT[P1].Y-POINT[P2].Y));} Double dis[1050];d ouble cost[1050][1050];int pre[1050];bool use[1050][1050];d ouble f[1050][1050];bool vis[1050]; Double Prim () {double res=0; memset (vis,true,sizeof (VIS)); Vis[1]=false; for (int i=2;i<=n;i++) pre[i]=1; pre[1]=0; for (int i=1;i<=n-1;i++) {int p=-1; Double minn=9999999999; for (int k=1;k<=n;k++) {if (Vis[k]) if (Dis[k]<minn) {p=k; MINN=DIS[K]; }} if (P==-1) return-1; Vis[p]=false; RES+=DIS[P]; Use[p][pre[p]]=use[pre[p]][p]=true; for (int k=1;k<=n;k++) {if (!vis[k]&&p!=k) F[p][k]=f[k][p]=max (Dis[p],f[k][pre[p]]); if (Vis[k]) if (Dis[k]>cost[p][k]) {dis[k]=cost[p][k]; Pre[k]=p; }}} return res;} int main () {int t;scanf ("%d", &t), while (t--) {tot=0; scanf ("%d", &n); for (int i=1;i<=n;i++) scanf ("%lf%lf%lf", &POINT[I].X,&POINT[I].Y,&POINT[I].P); for (int i=1;i<=n;i++) for (int k=i;k<=n;k++) {Cost[k][i]=cost[i][k]=disz (i,k); } for (int i=2;i<=n;i++) dis[i]=cost[1][i]; dis[1]=0; memset (f,0,sizeof (F)); memset (use,false,sizeof (use)); Double Ans=prim (); Enumeration Edge double pri=0; for (int i=1;i<=n;i++) {for (int k=i+1;k<=n;k++) {if (Use[i][k]) { Double peo= (POINT[I].P+POINT[K].P); Double w = cost[i][k]; Double ww=ans-w;Double BZ=PEO/WW; if (BZ>PRI) pri=bz; } else {double peo= (POINT[I].P+POINT[K].P); Double w = ans-f[i][k]; Double bz=peo/w; if (BZ>PRI) pri=bz; }}} printf ("%.2f\n", PRI);}}
UVA 10600 Test instructions is the minimum spanning tree value and sub-niche tree value
#include <stdio.h> #include <string.h> #include <algorithm> #include <map> #include <math.h >using namespace Std;int n;int m;int ans1,ans2;int cost[105][105];int dis[105];bool vis[105];int F[105][105];bool use [105] [105];int Pre[105];int Prim () {memset (vis,true,sizeof (VIS)); for (int i=1;i<=n;i++) pre[i]=1; memset (f,0,sizeof (F)); Vis[1]=false; int res=0; for (int i=1;i<=n-1;i++) {int p=-1; int minn=999999999; for (int j=1;j<=n;j++) {if (Vis[j]) {if (Minn>dis[j]) { MINN=DIS[J]; P=j; }}} if (minn==999999999) return-1; Vis[p]=false; Res+=minn; Use[p][pre[p]]=use[pre[p]][p]=false; for (int j=1;j<=n;j++) {if (!vis[j]&&j!=p) F[j][p]=f[p][j]=max (f[j][pre[p]],dis[p]);///Because there is no add j! =p forced WA A few times if (vis[j]&&dis[j]>cost[j][p]) {dis[j]=cost[j][p]; Pre[j]=p; }}} return res;} void second () {ans2=999999999; for (int i=1;i<=n;i++) {for (int k=1;k<=n;k++) {if (i!=k&&use[i][k]==true&&am P;pre[i]!=k&&pre[k]!=i) {if (Ans2>ans1-f[i][k]+cost[i][k]) { ANS2=ANS1-F[I][K]+COST[I][K]; }}}} return;} int main () {int t;scanf ("%d", &t), while (t--) {scanf ("%d%d", &n,&m); for (int i=1;i<=n;i++) for (int k=1;k<=n;k++) {if (i==k) cost[i][k]=0; else cost[i][k]=999999999; } for (int i=1;i<=m;i++) {int u,v,w; scanf ("%d%d%d", &u,&v,&w); Cost[u][v]=cost[v][u]=min (W,cost[u][v]); Use[u][v]=use[v][u]=true; } dis[1]=0; for (int i=2;i<=n;i++) dis[i]=cost[1][i]; Ans1=prim (); SecOnd (); printf ("%d%d\n", ans1,ans2);}}
UVA 104,621 graphs have no minimum spanning tree and sub-niche tree output answer or sub-decimal value
The difficulty is that the edge between the two points is not the only one here to think of using Kru to calculate the minimum spanning tree is the second approach mentioned at the beginning
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #include <map >using namespace Std;int n,m;struct node{int u,v,w;}; int Fa[105];node a[205];void init () {for (int i=1;i<=n;i++) fa[i]=i;} int find (int x) {if (fa[x]==x) return x; Return Fa[x]=find (Fa[x]);} void un (int x,int y) {int fx=find (x); int Fy=find (y); if (fx==fy) return; Fa[fx]=fy; return;} int CMP (node A,node b) {return A.W<B.W;} int gc[205];int Tot;int Kru () {tot=0;init (); int res=0;int cnt=0;if (cnt==n-1) return res;for (int i=0;i<m;i++) {int u=a[i].u; int v=a[i].v; int W=A[I].W; if (Find (U)!=find (v)) {gc[tot++]=i; Un (U,V); cnt++; Res+=w; } if (cnt==n-1) return res;} return-1;} int kru2 (int e) {init (); int cnt=0; int res=0; if (cnt==n-1) return res; for (int i=0;i<m;i++) {int u=a[i].u; int v=a[i].v; int W=A[I].W; if (I==gc[e]) Continue if (Find (U)!=find (v)) {un (U,V); cnt++; Res+=w; } if (cnt==n-1) return res; } return-1;} int main () {int t;int tt=0;scanf ("%d", &t), while (t--) {tt++; scanf ("%d%d", &n,&m); for (int i=0;i<m;i++) {int u,v,w; scanf ("%d%d%d", &u,&v,&w); A[i].u=u; A[i].v=v; A[i].w=w; } sort (a,a+m,cmp); int ans1,ans2; Ans1=kru (); printf ("Case #%d:", TT); if (ans1==-1) printf ("No way\n"); else {ans2=999999999; BOOL Cunzai=false; for (int i=0;i<tot;i++) {int ans3=kru2 (i); if (ans3!=-1) {cunzai=true; Ans2=min (ANS2,ANS3); }} if (!cunzai) printf ("No second way\n"); else printf ("%d\n", ans2); }/*for (int i=0;i<tot;i++) printf ("%d\n", Gc[i]); *///printf ("%d\n", ans1);}}
[Kuangbin take you to fly] thematic eight spanning tree-sub-niche into a tree part