标签:
该题就是最小生成树算法的变形,由于这个比值没有什么规律,不可能一下子算出最小情况,我们可以很容易发现,结点数非常少,所以我们可以枚举出m个结点的所有组合,这样,结点权值只和就确定了,为了使得比值最小,那么就要使得边权值之和最小,也就是最小生成树模板了。
枚举n个数中的m个可以有两种方法: dfs和二进制枚举子集。
该题我用的二进制,感觉比较方便。
细节参见代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include<set> using namespace std; typedef long long ll; const double INF = 1000000000; const int maxn = 500 + 5; int n,q,T,x,y,cnt,kase = 0,m,a,b,p[maxn],node[maxn]; double dx[maxn],dy[maxn]; int setfind(int x) { return p[x] == x ? x : p[x] = setfind(p[x]); } struct Edge{ int a,b,c; bool operator < (const Edge& rhs) const { return c < rhs.c; } }e[maxn*maxn]; void solve() { sort(e,e+cnt); double ans = INF; vector<int> res; for(int i=1;i<(1<<n);++i) { int c = 0; for(int j=0;j<n;++j) if(i & (1<<j)) ++c; if(c == m) { int vis[20] = {0};//标记那些结点在当前集合中 double cur = 1,cur1=0,cur2=0; for(int j=0;j<n;++j) if(i & (1<<j)) { vis[j+1] = 1; cur1 += node[j]; } for(int j=1;j<=n;j++) p[j] = j; for(int j=0;j<cnt;j++) { //最小生成树 int x = e[j].a, y = e[j].b; if(!vis[x]||!vis[y]) continue; x = setfind(e[j].a); y = setfind(e[j].b); if(x != y) { cur++; cur2 += e[j].c; p[x] = y; } if(cur == m) break; } if(abs(ans-cur2/cur1)<1e-6) { //更新答案 int cc = 0; bool ok = false; for(int j=1;j<=n;j++) if(vis[j]) { if(j < res[cc]) { ok = true; break; } else if(j > res[cc]) break; else cc++; } if(ok) { res.clear(); for(int j=1;j<=n;j++) if(vis[j]) res.push_back(j); } } else if(ans > cur2/cur1) { ans = cur2/cur1; res.clear(); for(int j=1;j<=n;j++) if(vis[j]) res.push_back(j); } } } for(int i=0;i<m;i++) { //打印解 if(i==0) printf("%d",res[i]); else printf(" %d",res[i]); } printf("\n"); } int main() { while(~scanf("%d%d",&n,&m)) { if(!n && !m) break; for(int i=0;i<n;i++) scanf("%d",&node[i]); cnt = 0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&a); if(i == j) continue; e[cnt].a = i; e[cnt].b = j; e[cnt++].c = a; } } solve(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 2489 Minimal Ratio Tree(最小生成树)
标签:
原文地址:http://www.cnblogs.com/AC-Arthur/p/4787189.html