hdu 2489 Minimal Ratio Tree

先用DFS求出全组合,然后每个组合求最小生成树。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int n, m, summ;
int u[10000][20];
int t[20], ff[20], nodecost[20], father[20];
int edgecost[20][20];
struct abc{ int start, end, cost; }node[20 * 20];
int find(int x)
{
    if (x != father[x]) father[x] = find(father[x]);
    return father[x];
}
void dfs(int tot, int i)
{
    int j;
    if (tot == m){ for (j = 0; j < m; j++) u[summ][j] = t[j]; summ++; return; }
    if (i > n) return;
    t[tot] = i; dfs(tot + 1, i + 1); dfs(tot, i + 1);
}
bool cmp(const abc&a, const abc&b){ return a.cost < b.cost; }
int main()
{
    int i, j, ii;
    while (~scanf("%d%d", &n, &m))
    {
        if (n == 0 && m == 0) break;
        summ = 0; dfs(0, 1);//DFS生成全组合
        for (i = 1; i <= n; i++) scanf("%d", &nodecost[i]);
        for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) scanf("%d", &edgecost[i][j]);
        int sx = 0;
        for (i = 1; i <= n; i++)
        {
            for (j = i + 1; j <= n; j++)
            {
                node[sx].start = i;
                node[sx].end = j;
                node[sx].cost = edgecost[i][j];
                sx++;
            }
        }
        sort(node, node + sx, cmp);
        double minratio = 999999999;
        int edge_weight, node_weight, anss;
        for (ii = 0; ii < summ; ii++)
        {
            memset(ff, 0, sizeof(ff));
            edge_weight = 0, node_weight = 0;
            for (i = 0; i <= n; i++) father[i] = i;
            for (i = 0; i < m; i++) ff[u[ii][i]] = 1, node_weight = node_weight + nodecost[u[ii][i]];
            for (i = 0; i < sx; i++)
            {
                if (ff[node[i].start] && ff[node[i].end])
                {
                    int x = find(node[i].start);
                    int y = find(node[i].end);
                    if (x != y)
                    {
                        father[x] = y;
                        edge_weight = edge_weight + node[i].cost;
                    }
                }
            }
            if (1.0*edge_weight / node_weight < minratio) minratio = 1.0*edge_weight / node_weight, anss = ii;
        }
        for (i = 0; i < m; i++)
        {
            if (i < m - 1) printf("%d ", u[anss][i]);
            else if (i == m - 1) printf("%d\n", u[anss][i]);
        }
    }
    return 0;
}

 

posted @ 2015-05-09 10:05  Fighting_Heart  阅读(484)  评论(0编辑  收藏  举报