hdu2489-DFS+最小生成树

来源:互联网 发布:绍兴网络电视台 回放 编辑:程序博客网 时间:2024/06/06 01:17
题意:
      给你n个点,和任意两点的距离,让你在这N个点中找到一个有m个点并且ratio最小的树.
                        ratio = sum(edge) / sum(node)

思路: N <= 15 直接DFS暴力枚举出 m个点,然后再这m个点中跑一边最小生成树,这m个点的sum(node) 可以直接加出来,而 sum(edge) 就是最小生数的值,然后求出ratio更新最小,记录答案. 


#include<stdio.h>#include<string.h>#include<algorithm>#define N 20#define inf 100000000;using namespace std;typedef struct{   int a ,b ,c;}NODE;bool camp(NODE a ,NODE b){   return a.c < b.c;}NODE node[N*N];int map[N][N] ,weight[N];int ans_num[N] ,now[N] ,n ,nn; int mer[N];double now_min;int finds(int x){   if(x == mer[x]) return x;   return mer[x] = finds(mer[x]);}void DFS(int s ,int t){   if(t == n + 1)   {      int tmp = 0 ,sum1 = 0 ,sum2 = 0 ,mm = 0;      for(int i = 1 ;i <= n ;i ++)      {         sum1 += weight[now[i]];         for(int j = i + 1 ;j <= n ;j ++)         {            node[++tmp].a = now[i];            node[tmp].b = now[j];            node[tmp].c = map[now[i]][now[j]];            if(mm < now[i]) mm = now[i];            if(mm < now[j]) mm = now[j];         }      }      sort(node + 1 ,node + tmp + 1 ,camp);      for(int i = 1 ;i <= mm ;i ++)      mer[i] = i;      mm = 0;      for(int i = 1 ;i <= tmp ;i ++)      {         int x = finds(node[i].a);         int y = finds(node[i].b);         if(x == y) continue;                  mer[x] = y;         sum2 += node[i].c;          if(++mm == n - 1) break;      }      //printf("%d %d %d %d\n" ,sum1 ,sum2 ,now[1] ,now[2]);      double nowm = sum2 * 1.0 / sum1;      if(nowm < now_min)      {         now_min = nowm;         for(int i = 1 ;i <= n ;i ++)         ans_num[i] = now[i];      }      return ;   }      for(int i = s + 1 ;i <= nn ;i ++)   {      now[t] = i;      DFS(i ,t + 1);   }}int main (){   int i;   while(scanf("%d %d" ,&nn ,&n) && n + nn)   {      for(i = 1 ;i <= nn ;i ++)      scanf("%d" ,&weight[i]);      for(i = 1 ;i <= nn ;i ++)      for(int j = 1 ;j <= nn ;j ++)      scanf("%d" ,&map[i][j]);      now_min = inf;      DFS(0 ,1);      for(i = 1 ;i < n ;i ++)      printf("%d " ,ans_num[i]);      printf("%d\n" ,ans_num[i]);   }   return 0;}

       





0 0