标签:map cst math pac == kruscal www blog 概念
所谓次小生成树,顾名思义就是从生成树中取出的第二小的生成树。
我们在前面已经说过最小生成树的概念及代码实现了,所以接下来要说的次小生成树应该比较简单理解了。
求次小生成树的两种方法
1:首先求出最小生成树T,然后枚举最小生成树上的边,计算除了枚举的当前最小
生成树的边以外的所有边形成的最小生成树Ti,然后求最小的Ti就是次小生成树。
2:首先计算出最小生成树T,然后对最小生成树上任意不相邻的两个点 (i,j)
添加最小生成树以外的存在的边形成环,然后寻找i与j之间最小生成树上最长的边删去,
计算map[i][j](最小生成树以外存在的边) 与 maxd[i][j](最小生成树上最长的边)
差值,求出最小的来,w(T)再加上最小的差值就是次小生成树了。
给定一个图,询问该图的最小生成树与次小生成树是否一致。
Kruscal实现版:
代码:
//Gang #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cmath> #define FOR(x,y,z) for(int x=y;x<=z;x++) #define REP(x,y,z) for(int x=y;x>=z;x--) #define ll long long using namespace std; int t,n,m,fa[10000],num,ans[10000]; int tot,bns,k,answer=99999999; struct node { int x,y,z; } e[101*101]; int cmp(node a,node b) { return a.z<b.z; } int find(int x) { int p,temp; p=x; while(fa[x]!=x) { x=fa[x]; } while(x!=p) { temp=fa[p]; fa[p]=x; p=temp; } return x; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); tot=0,bns=0; answer=99999999; memset(fa,0,sizeof(fa)); memset(ans,0,sizeof(ans)); FOR(i,1,m) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z); sort(e+1,e+m+1,cmp); FOR(i,1,n)fa[i]=i; FOR(i,1,m) { int dx=find(e[i].x),dy=find(e[i].y); if(dx!=dy) { tot++; fa[dx]=dy; ans[tot]=i; bns+=e[i].z; } if(tot==n-1)break; } FOR(i,1,tot) { k=0; num=0; FOR(j,1,n) fa[j]=j; sort(e+1,e+m+1,cmp); FOR(j,1,m) { if(j==ans[i])continue; int dx=find(e[j].x),dy=find(e[j].y); if(dx!=dy) { fa[dx]=dy; num++; k+=e[j].z; } if(num==n-1)break; } if(num==n-1)answer=min(k,answer); } if(answer==bns)printf("Not Unique!\n"); else printf("%d\n",bns); } return 0; }
prim实现版
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int inf = 0x7fffffff; const int size = 501; int firstpath[size][size]; int secondpath[size][size]; int pre[size]; int d[size]; int tree[size]; int t=0; bool flag[size]; int V,E; int qmax(int x,int y) { if(x>y)return x; else return y; } void prime(int u) { int i,j; for(i=1;i<=V;++i) { flag[i]=false; d[i]=inf; } for(i=1;i<=V;++i) for(j=i;j<=V;++j) secondpath[i][j]=secondpath[j][i]=-1; t=0; tree[t++]=u; flag[u]=true; for(i=1;i<V;++i) { int min=inf; int k; for(j=1;j<=V;++j) { if(d[j]>firstpath[u][j]) { d[j]=firstpath[u][j]; pre[j]=u; } if(!flag[j] && d[j]<min) { min=d[j]; k=j; } } for(j=0,u=k;j<t;++j) { secondpath[tree[j]][u]=qmax(secondpath[tree[j]][pre[u]],d[u]); secondpath[u][tree[j]]=secondpath[tree[j]][u]; } firstpath[pre[u]][u]=firstpath[u][pre[u]]=inf; flag[u]=true; tree[t++]=u; } for(i=1;i<=V;++i) for(j=i+1;j<=V;++j) if(firstpath[i][j]!=inf && firstpath[i][j]==secondpath[j][i]) { printf("Yes\n"); return ; } printf("No\n"); } int main() { int i,T,j,x,y,z; scanf("%d",&T); while(T--) { scanf("%d%d",&V,&E); for(i=1;i<=V;++i) for(j=i;j<=V;++j) firstpath[i][j]=firstpath[j][i]=inf; for(i=0;i<E;++i) { scanf("%d%d%d",&x,&y,&z); firstpath[x][y]=firstpath[y][x]=z; } prime(1); } return 0; }
标签:map cst math pac == kruscal www blog 概念
原文地址:http://www.cnblogs.com/oi-forever/p/7392470.html