zoukankan      html  css  js  c++  java
  • hdu 2489 MST+dfs

    http://acm.hdu.edu.cn/showproblem.php?pid=2489

    题目大意是有n个顶点的无向完全图,要你选m个点,使得m个点构成的图的m-1条边的权重之和比上m个点的值的和最小,即Sum(edge weight)/Sum(point weight)最小;

    由于题目的数据很小,因此我就直接暴力了。。。

    就是从n个点中先选m个点,对应一个最小值,然后对这m个点进行搜索就可以了。。。

    如果一开始就从第一个点就开始dfs,那么就可以保证最后的结果就是题目要求的。。。

    View Code
     1 #include<iostream>
     2 const int N=20;
     3 const int inf=10000000;
     4 using namespace std;
     5 
     6 int node[N];//点的权值
     7 int recode[N];//保存点
     8 int edge[N][N];
     9 int lowcost[N];
    10 int map[N][N];//用来保存边
    11 int path[N]; //保存路径
    12 int n,m;
    13 double MIN;
    14 
    15 double  prim(int v0){
    16     double sum=0;
    17     for(int i=1;i<=m;i++){
    18         lowcost[i]=map[v0][i];
    19     }
    20     lowcost[v0]=-1;
    21     for(int i=1;i<m;i++){
    22         int min=inf,v=-1;
    23         for(int j=1;j<=m;j++){
    24             if(lowcost[j]!=-1&&lowcost[j]<min){
    25                 v=j,min=lowcost[j];
    26             }
    27         }
    28         if(v!=-1){
    29             sum+=lowcost[v];
    30             lowcost[v]=-1;
    31             for(int k=1;k<=m;k++){
    32                 if(lowcost[k]!=-1&&map[v][k]<lowcost[k]){
    33                     lowcost[k]=map[v][k];
    34                 }
    35             }
    36         }
    37     }
    38     return sum;
    39 }
    40 void dfs(int v0,int count){
    41     recode[count]=v0;
    42     if(count==m){
    43         for(int i=1;i<=m;i++){
    44             map[i][i]=0;
    45             for(int j=i+1;j<=m;j++){
    46                 map[i][j]=map[j][i]=inf;
    47             }
    48         }
    49         for(int i=1;i<=m;i++){
    50             for(int j=1;j<=m;j++){
    51                 map[i][j]=edge[recode[i]][recode[j]];
    52             }
    53         }
    54         double s1=prim(1),s2=0;
    55         for(int i=1;i<=m;i++){
    56             s2+=node[recode[i]];
    57         }
    58         double s=s1/s2;
    59         if(s<MIN){
    60             MIN=s;
    61             //保存路径
    62             for(int i=1;i<=m;i++)
    63                 path[i]=recode[i];
    64         }
    65     }
    66     for(int i=v0+1;i<=n;i++)
    67         dfs(i,count+1);
    68 }
    69 
    70 int main(){
    71     while(scanf("%d%d",&n,&m)!=EOF){
    72         if(n==0&&m==0)break;
    73         for(int i=1;i<=n;i++){
    74             scanf("%d",&node[i]);
    75         }
    76         for(int i=1;i<=n;i++){
    77             for(int j=1;j<=n;j++){
    78                 scanf("%d",&edge[i][j]);
    79             }
    80         }
    81         MIN=1e18;
    82         for(int i=1;i<=n;i++)
    83             dfs(i,1);
    84         printf("%d",path[1]);
    85         for(int i=2;i<=m;i++){
    86             printf(" %d",path[i]);
    87         }
    88         printf("\n");
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    拼音输入法的数学原理
    搜索核心原理之网页和查询的相关性——TF-IDF
    Linux内核源码分析之调度、内核线程模型 And Centos7.2's Kernel Resource Analysis
    手把手教您定制化Centos6.x安装界面
    定制Centos系统(基于6.x)
    数据分析、数据挖掘之聚类、分类
    数据分析、数据挖掘之文档过滤、垃圾邮件
    数据分析、数据挖掘之特征分解、特征分析
    数据挖掘、数据分析之协同过滤、推荐系统、关联分析
    转载-“一代宗师”周金涛先生20个预言待验证
  • 原文地址:https://www.cnblogs.com/wally/p/2891107.html
Copyright © 2011-2022 走看看