Minimal Ratio Tree (hdu 2489 dfs+最小生成树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2489
dfs出每种排列组合情况
然后最小生成树
easy的
#include<bits/stdc++.h> using namespace std; int a[19]; int n,m,mp[19][19]; int b[19]; struct node { int x,y,s; }ydw[1900]; int jg[19]; double minn=1e9; bool cmp(node a,node b) { return a.s<b.s; } int p[19]; int findd(int x) { return x==p[x]?x:p[x]=findd(p[x]); } void join(int x,int y) { x=findd(x); y=findd(y); if(x!=y)p[y]=x; } double prim(int *b) { int kk=0; for(int i=0;i<=n;i++)p[i]=i;//注意到n for(int j=0;j<m;j++) { for(int i=j+1;i<m;i++) { ydw[kk].x=b[j]; ydw[kk].y=b[i]; ydw[kk++].s=mp[b[i]][b[j]]; } } sort(ydw,ydw+kk,cmp); int sum=0; for(int i=0;i<kk;i++) { if(findd(ydw[i].x)!=findd(ydw[i].y)) { join(ydw[i].x,ydw[i].y); sum+=ydw[i].s; } } int sumd=0; for(int i=0;i<m;i++) sumd+=a[b[i]]; return sum*1.0/sumd;//一开始直接return sum了 } void dfs(int k,int ans) { if(ans==m) { double ss=prim(b); if(ss<minn) { for(int i=0;i<m;i++) jg[i]=b[i]; minn=ss; } } for(int i=k+1;i<=n;i++) { b[ans]=i; dfs(i,ans+1); } } int main() { int i,j; while(scanf("%d%d",&n,&m),n||m) { memset(jg,0,sizeof(jg)); minn=1e9; for(i=1;i<=n;i++)scanf("%d",&a[i]); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d",&mp[i][j]); } } dfs(0,0); for(i=0;i<m;i++) { if(i==0)cout<<jg[i]; else cout<<" "<<jg[i]; } cout<<endl; } return 0; }