• hdu2489-DFS+最小生成树


    题意:
          给你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
    " ,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
    " ,ans_num[i]);
       }
       return 0;
    }
    

           





  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/csnd/p/12063280.html
Copyright © 2020-2023  润新知