zoukankan      html  css  js  c++  java
  • 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;
    }
    

           





  • 相关阅读:
    iOS 学习
    swift
    (九)Javabean与Jsp(来自那些年的笔记)
    (八)JSP 技术知识点总结(来自那些年的笔记)
    java抽象工厂模式
    java工厂方法模式
    java的简单工厂模式
    服务提供者框架讲解 之 myJDBC
    第一条:考虑用静态工厂方法代替构造器
    另辟蹊径的归并排序复杂度分析
  • 原文地址:https://www.cnblogs.com/csnd/p/12063279.html
Copyright © 2011-2022 走看看