最小生成树 最小树形图

来源:互联网 发布:什么软件可以讲故事 编辑:程序博客网 时间:2024/04/29 20:30
/****************************Kruskal算法*****************************/int father[maxn],n,m;int find(int x){if(father[x]!=x)father[x]=find(father[x]);return father[x];}void merge(int a,int b){int fx,fy;fx=find(a);fy=find(b);if(fx!=fy)father[fx]=fy;}struct node{int from,to,val;bool select;}edge[maxe];bool cmp(node a,node b){if(a.val!=b.val)return a.val<b.val;if(a.from!=b.from)return a.from<b.from;return a.to<b.to;}int kruskal(int t){int k=0;int i,x,y;int ans=0;for(i=1;i<=n;i++){father[i]=i;}sort(edge,edge+m,cmp);for(i=0;i<m;i++){if(k==n-1)break;if(edge[i].val<0) continue;if(i==t) continue;x=find(edge[i].from);y=find(edge[i].to);if(x!=y){merge(x,y);k++;ans+=edge[i].val;edge[i].select=true;}}return ans;}void init(){memset(edge,0,sizeof(edge));}



模板题 POJ 3164 代码

/**************************** 最小树形图  zhuliu算法先缩有向环*****************************/double zhuliu(int n,double map[maxn][maxn]){bool visit[maxn];bool flag[maxn];//缩点标记为ture,则该点已经被缩掉,否则依然存在int pre[maxn];double sum=0;int i,j,k;for(i=0;i<n;i++){flag[i]=false;map[i][i]=INF;}pre[0]=0;while(true){//求最短弧集合E0for(i=1;i<n;i++){if(flag[i]) continue;pre[i]=i;for(j=0;j<n;j++){if(!flag[j]&&map[j][i]<map[pre[i]][i])pre[i]=j;}if(pre[i]==i)return -1;}//检查E0for(i=1;i<n;i++){if(flag[i]) continue;//从当前点开始找环for(j=0;j<n;j++)visit[j]=false;visit[0]=true;j=i;do{visit[j]=true;j=pre[j];}while(!visit[j]);if(!j) continue; //没有找到环//收缩G中的有向环i=j;///将整个环的权值保存,累计入原图的最小树形图do{sum+=map[pre[j]][j];j=pre[j];}while(j!=i);j=i;//对与环上的点有关的边,修改边权do{for(k=0;k<n;k++){if(!flag[k]&&map[k][j]<INF&&k!=pre[j])map[k][j]-=map[pre[j]][j];}j=pre[j];}while(j!=i);//缩点,将整个环缩成i号点,所有与环上的点有关的边转移到点ifor(j=0;j<n;j++){if(j==i) continue;for(k=pre[i];k!=i;k=pre[k]){if(map[k][j]<map[i][j])map[i][j]=map[k][j];if(map[j][k]<map[j][i])map[j][i]=map[j][k];}}//标记环上其他的点为被缩掉for(j=pre[i];j!=i;j=pre[j]) flag[j]=true;//当前环缩点结束,形成新的图G1,跳出继续求G1的最小树形图break;}//如果所有的点都被检查切没有环存在,现在的环最短弧几何E0就是最小树形图,//累计入sum,算法结束if(i==n){for(i=1;i<n;i++){if(!flag[i])sum+=map[pre[i]][i];}break;}}}

最小生成树性质:

(1) 切割性质。假定所有边权值均不同。设S为既非空也非全集的V的子集,边e是满足一个端点在S内,另一个端点不在S内的所有边中权值最小的一个,则图G的所有生成树均包括e

(2)回路性质。假定所有编制均不同。设C是图G中的任意回路,边e是C上权值最大的边,则图G的所有生成树均不包括e。


0 0
原创粉丝点击