标签:
3 2 30 20 10 0 6 2 6 0 3 2 3 0 2 2 1 1 0 2 2 0 0 0
1 3 1 2
#include <iostream> #include<cstdio> #include<cstring> #include<climits> using namespace std; int a[20],f[20],p[20]; int mp[20][20]; bool vis[20]; int i,j,n,m; double ans; void prim() //最小生成树 { bool vis[20]; int dis[20]; int sumnode,sumedge=0,k; memset(vis,0,sizeof(vis)); vis[1]=1; sumnode=p[a[1]]; for(int i=1;i<=m;i++) dis[i]=mp[a[1]][a[i]]; for(int i=1;i<m;i++) { int minn=INT_MAX; for(int j=1;j<=m;j++) { if (!vis[j] && dis[j]<minn) { minn=dis[j]; k=j; } } vis[k]=1; sumedge+=minn; sumnode+=p[a[k]]; for(int j=1;j<=m;j++) if (!vis[j] && dis[j]>mp[a[k]][a[j]]) dis[j]=mp[a[k]][a[j]]; } double w=sumedge*1.0/sumnode; if (w<ans) //把最优解存放在f数组中 { ans=w; for(int i=1;i<=m;i++) f[i]=a[i]; } return; } void dfs(int k,int num)//dfs暴力枚举m个节点是哪几个存在a数组中 { if (num==m) { prim(); return; } if (k>n) return; if (!vis[k]) { vis[k]=1; a[num+1]=k; dfs(k+1,num+1); vis[k]=0; } dfs(k+1,num); return; } int main() { while(scanf("%d%d",&n,&m)) { if (n==0 && m==0) break; for(i=1;i<=n;i++) scanf("%d",&p[i]); for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&mp[i][j]); memset(vis,0,sizeof(vis)); ans=INT_MAX*1.0; dfs(1,0); for(i=1;i<m;i++) printf("%d ",f[i]); printf("%d\n",f[m]); } return 0; }
HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)
标签:
原文地址:http://www.cnblogs.com/stepping/p/5723095.html