#define N 55//所有点的个数 #define K 10//SteinerTree 最大顶点数,必须精确 #define INF 10000000 //SteinerTree 邻接矩阵模板。(稠密图)时间复杂度 O(N*2^K*(2^K+N)) int dp[(1<<K)+1][N]; int STV[N]; int SteinerTreeDP(int mat[N][N],int maxid,int *sameset,int size) { //mat为表示距离的邻接矩阵 //所有的标点从1到maxid //SteinerTree 所必须的点集为 sameset[0] 到 sameset[size-1] //函数放回最小Steiner Tree的值 for(int i=1;i<(1<<size);i++) for(int j=1;j<=maxid;j++) dp[i][j]=INF; for (int i=0; i<size; i++) { dp[(1<<i)][sameset[i]]=0; } for (int i=1;i<(1<<size);i++) { //step 1 for(int kk=1;kk<=maxid;kk++) { STV[kk]=0; for(int j = (i-1)&i ; j ;j = (j-1)&i) { dp[i][kk] = min(dp[i][kk],dp[j][kk]+dp[(~j)&i][kk]); } } //step 2 int kk,stmin=INF,stminid=0; for (int j = 0; stmin = INF, j < maxid; j++) { for (kk = 1; kk <= maxid; kk++) if (dp[i][kk] <= stmin && !STV[kk]) stmin = dp[i][stminid = kk]; for (STV[stminid]=1,kk = 1; kk <= maxid; kk++) if(STV[kk]==0) dp[i][kk] = min(dp[i][kk], dp[i][stminid] + mat[stminid][kk]); } } int tmin=INF; for(int j=1;j<=maxid;j++) tmin=min(tmin,dp[(1<<size)-1][j]); return tmin; }