POJ 3925 Minimal Ratio Tree 最小生成树

来源:互联网 发布:中金香港 知乎 编辑:程序博客网 时间:2024/05/22 08:13

思路是枚举+最小生成树,用DFS枚举或者二进制枚举。 

/*ID: sdj22251PROG: calfflacLANG: C++*/#include <iostream>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cmath>#include <ctime>#define MAX 100000000#define LOCA#define PI acos(-1.0)using namespace std;int d[16][16], node[16], v[16], dis[16], ans[16];int n, m;double mi;bool used[16];void search(){    int i, j, k, sum, weight;    sum = 0;    weight = 0;    memset(used, false, sizeof(used));    for(i = 0; i < m; i++)        dis[v[i]] = MAX;    for(i = 0; i < m; i++)        dis[v[i]] = d[v[0]][v[i]];    used[v[0]] = true;    for(i = 1; i < m; i++)    {        int mini = MAX;        int tmp = -1;        for(j = 0; j < m; j++)            if(!used[v[j]] && dis[v[j]] < mini)            {                mini = dis[v[j]];                tmp = v[j];            }        used[tmp] = true;        sum += mini;        for(j = 0; j < m; j++)        {            if(!used[v[j]] && d[v[j]][tmp] < dis[v[j]])                dis[v[j]] = d[v[j]][tmp];        }    }    for(j = 0; j < m; j++)        weight += node[v[j]];    double T = (double)sum / (double)weight;    if(T < mi)    {        for(j = 0; j < m; j++)            ans[j] = v[j];        mi = T;    }}void dfs(int x, int cnt){    v[cnt] = x;    if(cnt == m - 1)    {        search();        return;    }    for(int i = x + 1; i <= n; i++)        dfs(i, cnt + 1);}int main(){#ifdef LOCAL    freopen("ride.in","r",stdin);    freopen("ride.out","w",stdout);#endif    int i, j;    while(scanf("%d%d", &n, &m) != EOF)    {        if(n == 0 && m == 0) break;        for(i = 1; i <= n; i++)            scanf("%d", &node[i]);        for(i = 1; i <= n; i++)        {            for(j = 1; j <= n; j++)            {                scanf("%d", &d[i][j]);            }        }        mi = 100000000.0;        for(i = 1; i <= n; i++)        dfs(i, 0);        for(i = 0; i < m - 1; i++)            printf("%d ", ans[i]);        printf("%d\n", ans[m - 1]);    }    return 0;}