Minimal Ratio Tree

最小比率树算法解析与实现
本文详细介绍了最小比率树的概念及其求解方法,通过实例展示了如何在一个完全加权图中寻找具有最小比率的子图,并提供了算法实现的源代码。

Minimal Ratio Tree

Problem Description

For a tree, which nodes and edges are all weighted, the ratio of it is calculated according to the following equation.



Given a complete graph of n nodes with all nodes and edges weighted, your task is to find a tree, which is a sub-graph of the original graph, with m nodes and whose ratio is the smallest among all the trees of m nodes in the graph.

 

Input

Input contains multiple test cases. The first line of each test case contains two integers n (2<=n<=15) and m (2<=m<=n), which stands for the number of nodes in the graph and the number of nodes in the minimal ratio tree. Two zeros end the input. The next line contains n numbers which stand for the weight of each node. The following n lines contain a diagonally symmetrical n×n connectivity matrix with each element shows the weight of the edge connecting one node with another. Of course, the diagonal will be all 0, since there is no edge connecting a node with itself.



All the weights of both nodes and edges (except for the ones on the diagonal of the matrix) are integers and in the range of [1, 100].

The figure below illustrates the first test case in sample input. Node 1 and Node 3 form the minimal ratio tree.

 

Output

For each test case output one line contains a sequence of the m nodes which constructs the minimal ratio tree. Nodes should be arranged in ascending order. If there are several such sequences, pick the one which has the smallest node number; if there's a tie, look at the second smallest node number, etc. Please note that the nodes are numbered from 1 .

 

Sample Input

3 2
30 20 10
0 6 2
6 0 3
2 3 0
2 2
1 1
0 2
2 0
0 0

Sample Output

1 3
1 2

 

 

自己的解答:

最后的错误是输出格式错了,在数字的最后是没有空格的...

#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;


int n,m;
int node[20],edge[20][20];
int a[20];
int tmin[20];
int minValue[2] ;  //0 分子  1 分母

int prim(){
	int i,j;
	int visE[20][20];
	int visN[20],p1,p2;
	int minE ;
	int sumNum = 0;
	memset(visE,0,sizeof(visE));
	memset(visN, 0, sizeof(visN));
	int nodeN = 1;
	visN[a[0]] = 1;
	while(1){
		minE = -1;
		for(i=0 ; i<m ; i++){
			for(j= i+1 ; j<m ;j++) if(visE[a[i]][a[j]] == 0 &&
				((visN[a[i]]!=0 && visN[a[j]]==0) || (visN[a[i]]==0 && visN[a[j]]!=0)) //点必须在已找到的点种扩展
				){
				if(minE == -1 || minE > edge[a[i]][a[j]]){
					minE = edge[a[i]][a[j]];
					p1 = a[i];
					p2 = a[j];
				}
			}
		}
		visE[p1][p2] = 1;
		visN[p1] = 1;
		visN[p2] = 1;
		sumNum += minE;
		nodeN++;
		if(nodeN == m)
			break;
	}
	return sumNum;
}

void zuhe(int _i,int cur)
{
	int i;
	if(cur==m)
	{
		// 处理
		int sumN=0,sumE=0;
		for(i=0 ; i<m ; i++){
			sumN += node[a[i]];
		}
		sumE = prim();
		if(minValue[0] == -1 || minValue[0]*sumN > sumE*minValue[1]){
			minValue[0] = sumE;
			minValue[1] = sumN;
			memcpy(tmin, a, sizeof(a));
		}
		return;
	}

	for(i=_i; i<n ; i++){
		a[cur] = i;
		zuhe(i+1,cur+1);
	}
}

int main(){

	int i,j;
	
	while(1)
	{
		cin>>n>>m;
		if(n == 0 && m == 0)
			break;

		for(i=0; i<n; i++)
		{
			cin>>node[i];  //节点的权值
		} //for
		for(i=0; i<n; i++)
		{
			for(j=0; j<n; j++)
			{
				cin>>edge[i][j];  // 边的权值
			} //for
		} //for

		minValue[0] = -1;
		memset(tmin , -1 ,sizeof(tmin));

		zuhe(0,0);

		//cout<<"ans:";
		cout<<tmin[0]+1;
		for(i=1 ; i<m ; i++){
			cout<<" "<<tmin[i]+1;
		}
		cout<<endl;


	}//while
	return 0;
}
 

 

 

解释下这些选项的功能:Options: -call_tree Create a context-sensitive call tree -compact_labels Show minimal headers -divide_by Ratio to divide all samples before visualization -drop_negative Ignore negative differences -edgefraction Hide edges below <f>*total -focus Restricts to samples going through a node matching regexp -hide Skips nodes matching regexp -ignore Skips paths going through any nodes matching regexp -intel_syntax Show assembly in Intel syntax -mean Average sample value over first value (count) -nodecount Max number of nodes to show -nodefraction Hide nodes below <f>*total -noinlines Ignore inlines. -normalize Scales profile based on the base profile. -output Output filename for file-based outputs -prune_from Drops any functions below the matched frame. -relative_percentages Show percentages relative to focused subgraph -sample_index Sample value to report (0-based index or name) -show Only show nodes matching regexp -show_from Drops functions above the highest matched frame. -showcolumns Show column numbers at the source code line level. -source_path Search path for source files -tagfocus Restricts to samples with tags in range or matched by regexp -taghide Skip tags matching this regexp -tagignore Discard samples with tags in range or matched by regexp -tagleaf Adds pseudo stack frames for labels key/value pairs at the callstack leaf. -tagroot Adds pseudo stack frames for labels key/value pairs at the callstack root. -tagshow Only consider tags matching this regexp -trim Honor nodefraction/edgefraction/nodecount defaults -trim_path Path to trim from source paths before search -unit Measurement units to display
最新发布
09-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值