hdu2489 Minimal Ratio Tree

时间:2023-03-09 01:31:32
hdu2489 Minimal Ratio Tree

hdu2489 Minimal Ratio Tree

题意:一个 至多  n=15 的 完全图 ,求 含有 m 个节点的树 使 边权和 除 点权和 最小

题解:枚举 m 个 点 ,然后 求 最小生成树

自己粗心。。。。WA 了 好多次……(233333 )

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <string>
using namespace std;
typedef long long ll;
const double ESP = 10e-;
const int MOD = ;
typedef long long LL;
const int MAXN = + ; int graph[MAXN][MAXN];
int node[MAXN];
int tmp[MAXN];
int dist[MAXN];
int ans[MAXN];
double ansMi;
int n,m;
bool vis[MAXN];
double prim(){
double dis = ;
memset(vis,,sizeof(vis));
int cur = ;
vis[cur] = ;
for(int i = ;i < m;i++){
dist[i] = graph[ tmp[cur] ][ tmp[i] ];
} for(int i = ;i < m-;i++){
int mi = 0x7ffffff;
int k;
for(int j = ;j < m;j++){
if(!vis[j] && dist[j] < mi){
mi = dist[j];
k = j;
}
}
cur = k;
vis[cur] = ;
dis += mi;
for(int j = ;j < m;j++){
if(!vis[j] && dist[j] > graph[ tmp[cur] ][ tmp[j] ]){
dist[j] = graph[ tmp[cur] ][ tmp[j] ];
}
}
}
return dis;
} void dfs(int v,int cnt){
if(cnt == m-){
double h = ;
for(int i = ;i < m;i++){
h += node[ tmp[i] ];
}
double b = prim();
double tt = b/h;
if(tt - ansMi < -(1e-)){
ansMi = tt;
for(int i = ;i < m;i++){
ans[i] = tmp[i];
}
}
return;
}
for(int i = v+;i<= n;i++){
tmp[cnt+] = i;
dfs(i,cnt+);
}
} int main(){
// freopen("input.txt","r",stdin);
while(~scanf("%d%d",&n,&m) && n &&m){
for(int i = ;i <= n;i++){
scanf("%d",&node[i]);
}
for(int i = ;i <= n;i++){
for(int j = ;j <= n;j++){
scanf("%d",&graph[i][j]);
}
}
ansMi = 10e10;
for(int i = ;i <= n;i++){
tmp[] = i;
dfs(i,);
}
for(int i = ;i < m-;i++){
printf("%d ",ans[i]);
}
printf("%d\n",ans[m-]);
}
return ;
}