想到枚举m个点,然后求最小生成树,ratio即为最小生成树的边权/总的点权。
但是怎么枚举这m个点,实在不会。
网上查了一下大牛们的解法,用dfs枚举,没想到dfs还有这么个作用。

参考链接:http://blog.csdn.net/xingyeyongheng/article/details/9373271

#include <stdio.h>
#include <string.h>
#include <set>
#include <vector>
#include <queue> using namespace std; const int INF=0x3f3f3f3f;
int n,m,tot; //tot为选取的m个点的总权值
int choseNode[]; //存储选取的m个点
int tmp[]; //存储最小ratio的m个点
int nodew[],w[][]; //nodew[i]存储点i的权值,w[i][j]存储边的权值
int dis[],vis[];
double minratio=0x3f3f3f3f; int prim(){
int ans=;
memset(dis,INF,sizeof(dis));
memset(vis,,sizeof(vis));
int t,idx;
dis[choseNode[]]=;
for(int i=;i<=m;i++){
t=INF;
for(int i=;i<m;i++){
if(!vis[choseNode[i]] && dis[choseNode[i]]<t){
t=dis[choseNode[i]];
idx=choseNode[i];
}
}
vis[idx]=;
ans+=t;
for(int i=;i<m;i++){
int u=choseNode[i];
if(!vis[u] && w[idx][u]<dis[u]){
dis[u]=w[idx][u];
}
}
}
return ans;
}
/*
dfs枚举m个点,num代表目前选取了多少个点,k代表第num个点为k。
表示前num个点选自1~k,剩余的点从k+1~n中选。
*/
void dfs(int k,int num){
if(num==m){
tot=;
for(int i=;i<m;i++){
tot+=nodew[choseNode[i]];
}
int sum=prim();
double tmpratio=sum*1.0/tot;
if(tmpratio<minratio){
minratio=tmpratio;
for(int i=;i<m;i++){
tmp[i]=choseNode[i];
}
}
return; //忘记写return了。。。
}
//若剩余的点的个数(n-k)加上目前选取的个数num小于m的话,说明即使接下来n-k个点都选取,也选不足m个点,直接return
if(n-k+num<m)
return;
for(int i=k+;i<=n;i++){
//选的点用数组存起来
choseNode[num]=i;
dfs(i,num+);
}
}
int main()
{
int a;
while(scanf("%d%d",&n,&m)!=EOF){
if(n== && m==)
break;
memset(w,,sizeof(w));
minratio=INF*0.1;
for(int i=;i<=n;i++){
scanf("%d",&nodew[i]);
}
for(int i=;i<=n;i++){
for(int j=;j<=i;j++)
scanf("%d",&a);
for(int j=i+;j<=n;j++){
scanf("%d",&a);
w[i][j]=w[j][i]=a;
}
}
for(int i=;i<=n;i++){
choseNode[]=i;
dfs(i,);
}
for(int i=;i<m-;i++){
printf("%d ",tmp[i]);
}
printf("%d",tmp[m-]);
printf("\n");
}
return ;
}

最后再附上网上看到的另一种dfs枚举的写法:

//调用时:dfs(1,0,0);

//dep表示点的编号,cnt表示选取的点的个数,sum_pw表示目前选取了cnt个点后总的点权值
void dfs(int dep, int cnt, int sum_pw) {
if(cnt == m) {
...;
return ;
}
if(dep == n + ) return ;
use[dep] = true; //选取点dep,这里use[i]=true表示选取点i,在用prim求最小生成树的时候有用
dfs(dep + , cnt + , sum_pw + weight[dep]);
use[dep] = false; //不选取点dep
dfs(dep + , cnt, sum_pw);
}

HDU 2489 Minimal Ratio Tree(dfs枚举+最小生成树)的更多相关文章

  1. HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

    Minimal Ratio Tree Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  2. HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2489 Problem Description For a tree, which nodes and ...

  3. HDU 2489 Minimal Ratio Tree(暴力+最小生成树)(2008 Asia Regional Beijing)

    Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated accord ...

  4. HDU 2489 Minimal Ratio Tree 最小生成树+DFS

    Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. HDU 2489 Minimal Ratio Tree(prim+DFS)

    Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  6. hdu 2489 Minimal Ratio Tree

    http://acm.hdu.edu.cn/showproblem.php?pid=2489 这道题就是n个点中选择m个点形成一个生成树使得生成树的ratio最小.暴力枚举+最小生成树. #inclu ...

  7. hdu2489 Minimal Ratio Tree dfs枚举组合情况+最小生成树

    #include <stdio.h> #include <set> #include <string.h> #include <algorithm> u ...

  8. Minimal Ratio Tree HDU - 2489

    Minimal Ratio Tree HDU - 2489 暴力枚举点,然后跑最小生成树得到这些点时的最小边权之和. 由于枚举的时候本来就是按照字典序的,不需要额外判. 错误原因:要求输出的结尾不能有 ...

  9. HDU2489 Minimal Ratio Tree 【DFS】+【最小生成树Prim】

    Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

随机推荐

  1. Codevs 1669 运输装备

    时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 德国放松对英国的进攻后,把矛头指向了东北—— ...

  2. oc常见误区

    1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...

  3. 【风马一族_Android】手机与电脑通过adb进行连接

    1:打开电脑的命令行 cmd 2:adb devices 查看与电脑连接的手机或模拟器的名称 3:准备要安装的apk.记住手机的名称 4:adb –s <模拟器名称> install  & ...

  4. 使用HttpWebRequest以及HttpWebResponse读取Http远程文件

     主页>杂项技术>.NET(C#)> 使用HttpWebRequest以及HttpWebResponse读取Http远程文件 jackyhwei 发布于 2010-08-15 21: ...

  5. ADO.NET笔记——基本概念

    ADO.NET中的主要对象: Connection:连接对象.用于建立从应用程序到数据库服务器指定数据库的连接通道 Command:命令对象.用于执行增删查改等数据库语句命令 DataReader:数 ...

  6. Linux下vsftpd搭建过程(防火墙版)

    1.确认主机IP [root@www data]# ifconfig  eth0      Link encap:Ethernet  HWaddr 00:0C:29:22:05:B8         ...

  7. 万能的SQLHelper帮助类

    /// <summary> /// 数据库帮助类 /// </summary> public class SQLHelper { private static string c ...

  8. About Curah

    相信下列场景对您来说一点都不陌生:您遇到一个问题,花了好几个小时在网上搜寻解答和可靠的技术内容.即使前往许多技术博客和论坛翻箱倒柜后,还是无法确定要相信谁,也不知道该选哪个答案. Curah! 网站就 ...

  9. WebDev.WebServer40.exe已停止工作

    今天写程序的遇到这个错误 错误的原因是代码中有死循环

  10. ubuntu 下dbus的环境搭建和使用

    从https://launchpad.net/ubuntu/+source/dbus/1.10.6-1ubuntu2下载需要的dbus包,然后解压,./configure make && ...