?? 最小樹形圖(鄰接陣形式).txt
字號:
//多源最小樹形圖,edmonds算法,鄰接陣形式,復(fù)雜度O(n^3)
//返回最小生成樹的長度,構(gòu)造失敗返回負值
//傳入圖的大小n和鄰接陣mat,不相鄰點邊權(quán)inf
//可更改邊權(quán)的類型,pre[]返回樹的構(gòu)造,用父結(jié)點表示
//傳入時pre[]數(shù)組清零,用-1標(biāo)出源點
#include <string.h>
#define MAXN 120
#define inf 1000000000
typedef int elem_t;
elem_t edmonds(int n,elem_t mat[][MAXN*2],int* pre){
elem_t ret=0;
int c[MAXN*2][MAXN*2],l[MAXN*2],p[MAXN*2],m=n,t,i,j,k;
for (i=0;i<n;l[i]=i,i++);
do{
memset(c,0,sizeof(c)),memset(p,0xff,sizeof(p));
for (t=m,i=0;i<m;c[i][i]=1,i++);
for (i=0;i<t;i++)
if (l[i]==i&&pre[i]!=-1){
for (j=0;j<m;j++)
if (l[j]==j&&i!=j&&mat[j][i]<inf&&(p[i]==-1||mat[j][i]<mat[p[i]][i]))
p[i]=j;
if ((pre[i]=p[i])==-1)
return -1;
if (c[i][p[i]]){
for (j=0;j<=m;mat[j][m]=mat[m][j]=inf,j++);
for (k=i;l[k]!=m;l[k]=m,k=p[k])
for (j=0;j<m;j++)
if (l[j]==j){
if (mat[j][k]-mat[p[k]][k]<mat[j][m])
mat[j][m]=mat[j][k]-mat[p[k]][k];
if (mat[k][j]<mat[m][j])
mat[m][j]=mat[k][j];
}
c[m][m]=1,l[m]=m,m++;
}
for (j=0;j<m;j++)
if (c[i][j])
for (k=p[i];k!=-1&&l[k]==k;c[k][j]=1,k=p[k]);
}
}
while (t<m);
for (;m-->n;pre[k]=pre[m])
for (i=0;i<m;i++)
if (l[i]==m){
for (j=0;j<m;j++)
if (pre[j]==m&&mat[i][j]==mat[m][j])
pre[j]=i;
if (mat[pre[m]][m]==mat[pre[m]][i]-mat[pre[i]][i])
k=i;
}
for (i=0;i<n;i++)
if (pre[i]!=-1)
ret+=mat[pre[i]][i];
return ret;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -