首页 > 代码库 > {POJ}{3925}{Minimal Ratio Tree}{最小生成树}
{POJ}{3925}{Minimal Ratio Tree}{最小生成树}
题意:给定完全无向图,求其中m个子节点,要求Sum(edge)/Sum(node)最小。
思路:由于N很小,枚举所有可能的子节点可能情况,然后求MST,memset()在POJ里面需要memory头文件。
#include <iostream>#include <vector>#include <map>#include <cmath>#include <memory>#include <algorithm>#include <cstdio>#include <cstdlib>using namespace std;const int MAXN = 100;const int INF = 1<<30; #define CLR(x,y) memset(x,y,sizeof(x))#define MIN(m,v) (m)<(v)?(m):(v)#define MAX(m,v) (m)>(v)?(m):(v)#define ABS(x) ((x)>0?(x):-(x))#define rep(i,x,y) for(i=x;i<y;++i)int n,m,k;double ans = 0;int select[MAXN];int g[MAXN][MAXN];int val[MAXN];int visit[MAXN];double dist[MAXN];int ind[MAXN];double Prim(){ int i,j,tmp,mark_i; int mark_min; int sum_node = 0; int sum_edge = 0; for(i = 0; i < n; ++i) { dist[i] = INF; visit[i] = 0; } for(i = 0; i < n; ++i) if(select[i]>0) { dist[i] = 0; break; } int cnt = 0; for(i = 0; i < n; ++i,++cnt) { if(cnt>=m) break; mark_min = INF; for(j = 0; j < n; ++j) { if(select[j]>0 && !visit[j] && mark_min>dist[j]) { mark_min = dist[j]; mark_i = j; } } visit[mark_i] = 1; sum_edge += dist[mark_i]; for( j = 0; j < n; ++j) { if(visit[j]==0 && select[j]>0 && dist[j] > g[mark_i][j]) dist[j] = g[mark_i][j]; } } for( i = 0; i < n; ++i) if(select[i] > 0 ) sum_node += val[i]; return double(sum_edge)/sum_node;}int DFS(int cur, int deep){ double res = INF; select[cur] = 1; if(deep < m) { for(int i = cur+1; i < n; ++i) { DFS(i,deep+1); } } if(deep == m) { res = Prim(); if(res < ans) { ans = res; for(int i = 0; i < n; ++i) ind[i] = select[i]; } } select[cur] = 0; return 0;}int Solve(){ while(scanf("%d%d",&n,&m)!=EOF) { if(n == 0 && m == 0) break; for(int i = 0 ; i < n; ++i) scanf("%d",&val[i]); for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) { scanf("%d",&g[i][j]); } CLR(select,0); ans = INF; for(int i = 0 ; i < n; ++i) DFS(i,1); int tag = 0; for(int i = 0; i < n; ++i) if(ind[i] > 0) if(tag == 0) { printf("%d",i+1); tag = 1; } else printf(" %d",i+1); printf("\n"); } return 0;}int main(){ Solve(); return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。