您的位置:首页 > 其它

hdu 2489 Minimal Ratio Tree dfs枚举组合情况+最小生成树★

2014-03-31 17:43 507 查看
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string.h>

using namespace std;

#define MAXN 20
#define INF 1e20;

int n, m;
int value[MAXN];
int c[MAXN][MAXN];
int ans[MAXN];
int copys[MAXN];
bool vis[MAXN];
bool choice[MAXN];
int pre[MAXN];

struct Edge
{
int u, v;
double w;
}edge[MAXN * MAXN];

int e;

void add(int u, int v, int val)
{
edge[e].u = u;
edge[e].v = v;
edge[e++].w = val;
}

bool cmp(Edge a, Edge b)
{
return a.w < b.w;
}

int find(int x)
{
return x == pre[x] ? x : (pre[x] = find(pre[x]));
}

double cal(int co[])
{
memset(choice, false, sizeof(choice));
double temp = 0;

for (int i = 0; i < m; i++)
{
choice[co[i]] = true;
temp += value[co[i]];
}

int num = 1;
double res = 0;
for (int i = 0; i < n; i++)
{
pre[i] = i;
}

for (int i = 0; i < e; i++)
{
int u = edge[i].u, v = edge[i].v, w = edge[i].w;

if (choice[u] && choice[v])
{
int fu = find(u), fv = find(v);

if (fu != fv)
{
pre[fu] = fv;
res += w;
num++;
}

if (num == m)
{
return res / temp;
}
}
}
}

double temp;

void dfs(int x, int len)
{
if (len == m)
{
double r = cal(copys);

if (r - temp < -(1e-12))
{
temp = r;
for (int i = 0; i < m; i++)
{
ans[i] = copys[i];
}
}

return ;
}
else
{
for (int i = x; i < n; i++)
{
if (!vis[i])
{
vis[i] = true;
copys[len++] = i;
dfs(i, len);
len--;
vis[i] = false;
}
}
}
}

void input()
{
int u, v;
double val;

while (cin >> n >> m)
{
if (!n && !m)
{
break;
}

e = 0;

memset(vis, false, sizeof(vis));

for (int i = 0; i < n; i++)
{
cin >> value[i];
}

for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> val;

if (i < j)
{
add(i, j, val);
}
}
}

sort(edge, edge + e, cmp);

temp = INF;

dfs(0, 0);

for (int i = 0; i < m; i++)
{
cout << ans[i] + 1;

if (i != m - 1)
{
cout << ' ';
}
}

cout << endl;
}
}

int main()
{
input();
return 0;
}


注意精度(看了别人的)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: