POJ 3925 Minimal Ratio Tree 最小生成树

原创 2014年09月15日 22:23:57

题目大意:

给定N个点(2<=N<=15)的图,求在顶点数满足M个的子图中,满足如下式子的最小值。

Ratio=\frac{\sum{edgeweight}}{\sum{nodeweight}}



题目分析:

题目求得是Ratio的最小值,Ratio=子图中的边权和/点权和 ,考虑在某一满足条件的子图中,∑nodeweight是定值,则在子图中求Ratio的最小值就是子图的最小生成树。题目的数据比较小,对于N<=15,共有2^15次方种可能子图,每次求Prim复杂度为O(M^2),是可以接受的。

其中比较关键的有两点:

1:求Ratio(上文已讲过)

2:枚举子图,类似枚举子图问题我们可以用dfs回溯完成。

      如下是比较关键的几行代码

      dfs(int dep,int pos)

      {

             ********

           use[dep]=pos;

           dfs(dep+1,pos+1)//枚举到pos位置的下一个

           //这样我们可以保证子图不重复;

            dfs(dep,pos+1);//在当前的dep下更改成pos+1

      }

如下代码(附带注释):

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 16
#define INF 1000000
using namespace std;
int n,m,node[N],edge[N][N],fin[N],d[N],use[N];
double ans;
double Prim()
{
	int s,pos,res,cnt=0;
	for(int i=0;i<m;i++) 
	   d[use[i]]=INF;
	s=use[0];
	for(int i=1;i<=m-1;i++)
	{
		res=INF;
		d[s]=-1;
		for(int j=0;j<m;j++)
		{
			if(s!=use[j]&&d[use[j]]>0)
			{
				d[use[j]]=min(d[use[j]],edge[s][use[j]]);
				if(d[use[j]]<res)
				{
					res=d[use[j]];
					pos=use[j];	
				}	
			}
		}
		s=pos;
		cnt+=res;	
	}
	res=0;
	for(int i=0;i<=m-1;i++)
		res+=node[use[i]];
	return 1.0*cnt/res;	
}
void dfs(int dep,int pos)
{
	if(dep>m||pos>n+1)//注意是n+1 
		return;
	if(dep==m)
	{
		double tem=Prim();
		if(tem<ans)
		{
			ans=tem;
			for(int i=0;i<m;i++)
			   fin[i]=use[i];
			return ;
		}
	}
	use[dep]=pos;//重建点 
	dfs(dep+1,pos+1);
	dfs(dep,pos+1);
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if(!n&&!m)	
			break;
		for(int i=1;i<=n;i++)
		    scanf("%d",&node[i]);
		for(int i=1;i<=n;i++)
		    for(int j=1;j<=n;j++)
			scanf("%d",&edge[i][j]);
		ans=INF;
		dfs(0,1);//从0,1开始搜索 
		for(int i=0;i<m;i++)
		    printf("%d%s",fin[i],i==m-1?"\n":" ");	
	}	
//	while(1);
	return 0;
}


 

POJ 3925 Minimal Ratio Tree 最小生成树

思路是枚举+最小生成树,用DFS枚举或者二进制枚举。  /* ID: sdj22251 PROG: calfflac LANG: C++ */ #include #include #includ...

POJ 3925 Minimal Ratio Tree

题目大意: 题目链接 注释代码: 无注释代码: 单词解释:

POJ3925 Minimal Ratio Tree

Minimal Ratio Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1071...
  • mowayao
  • mowayao
  • 2013年10月02日 22:15
  • 586

2489 Minimal Ratio Tree 最小生成树(选边)

题意: 给n个点及各点间的距离,从中选出m个点 ,使得  边权的和 / 点权的和  最小。 思路: 从n个点中选出m个点(枚举每种可能的情况),计算出它的。。。最小值。所以可以用dfs枚举出各种情况...
  • LiWen_7
  • LiWen_7
  • 2012年08月10日 10:29
  • 608

hdu2489Minimal Ratio Tree 最小生成树

//给一个完全图,在其中找一颗树,使得边的权值之和除以点的权值之和最小 //由于n...
  • cq_pf
  • cq_pf
  • 2015年08月03日 15:17
  • 489

HDU2489Minimal Ratio Tree(最小生成树+状态压缩)

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

HDU 2489 Minimal Ratio Tree(最小生成树)

该题就是最小生成树算法的变形,由于这个比值没有什么规律,不可能一下子算出最小情况,我们可以很容易发现,结点数非常少,所以我们可以枚举出m个结点的所有组合,这样,结点权值只和就确定了,为了使得比值最小,...

hdu Minimal Ratio Tree(最小生成树---prim)

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

dfs枚举 + 最小生成树 hdoj2489 Minimal Ratio Tree

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2489题目大意是,给你一个图,这个图不仅有边权,还有点权,图中共有n个点,问做一棵包含m个结点的生成树...

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

HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 3925 Minimal Ratio Tree 最小生成树
举报原因:
原因补充:

(最多只允许输入30个字)