Minimal Ratio Tree HDU - 2489

原题链接

考察:最小生成树+枚举

错误思路:

       枚举m个点,将m个点的边权值计入和,与点权值和作商求最小值

上面的思路错在题目是要求求m个点的树的比率最小.如果边权值不去掉一个而全部计入的话就会WA

正确思路:

       枚举m个点,求最小生成树

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 const int N = 20,Max = 0x3f3f3f3f;
 6 int node[N],m,n,g[N][N],path[N],cnt,p[N];
 7 double ans; 
 8 bool vis[N];
 9 vector<int> v;
10 struct Edge{
11     int u,v,w;
12     bool operator<(Edge x){
13         return this->w<x.w;
14     }
15 }edge[N*N];
16 int findf(int x)
17 {
18     if(x!=p[x]) p[x] = findf(p[x]);
19     return p[x];
20 }
21 void dfs(int k,int st,double sum)
22 {
23     if(k==m){
24         cnt = 0;
25         for(int i=1;i<=n;i++) p[i] = i;
26         for(int i=0;i<k;i++)
27             for(int j=i+1;j<k;j++)
28                 edge[++cnt] = {path[i],path[j],g[path[i]][path[j]]};
29         sort(edge+1,edge+cnt+1);
30         double esum = 0;
31         for(int i=1;i<=cnt;i++){
32             int x = findf(edge[i].u), y = findf(edge[i].v);
33             if(x!=y){
34                 p[x] = y;
35                 esum+=edge[i].w;
36             }
37         }
38         if(esum/sum<ans){
39             ans = esum/sum;
40             v.clear();
41             for(int i=0;i<k;i++) v.push_back(path[i]);
42         }
43         return;
44     }
45     for(int i=st;i<=n;i++){
46         if(!vis[i])
47         {
48             vis[i] = 1;
49             path[k] = i;
50             dfs(k+1,i+1,sum+node[i]);
51             vis[i] = 0;
52         }
53     }
54 }
55 int main()
56 {
57     while(scanf("%d%d",&n,&m)&&n)
58     {//枚举m个点 
59         fill(vis,vis+N,0); ans = Max;
60         v.clear();
61         for(int i=1;i<=n;i++) scanf("%d",&node[i]);
62         for(int i=1;i<=n;i++)
63            for(int j=1;j<=n;j++)
64               scanf("%d",&g[i][j]);
65         dfs(0,1,0);
66         for(int i=0;i<v.size();i++) printf("%d%c",v[i],i==v.size()-1?'\n':' ');
67     }
68     return 0;
69 }

 

posted @ 2021-01-14 22:38  acmloser  阅读(68)  评论(0编辑  收藏  举报