首页 > 代码库 > HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)
HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2489
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.
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.
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
Source
2008 Asia Regional Beijing
题意:
给出n个点,要从中选出m个点,要求选出的这m个点的所有边的边权值/点权值要最小!
并要输出所选的这m个点,如果有多种选择方法,那么就输出第一个点小的方案,如果第一个点相同就输出第二个点小的,一次类推!
PS:
由于这题的n比较小,只有15,所以可以先dfs枚举出所选择的点,然后在用最小生成树Prim算出最小的边权值的和;
代码如下:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> using namespace std; #define INF 1e18; const double eps = 1e-9; const int maxn = 17; int n, m; int e_val[maxn][maxn]; int node[maxn]; int ansn[maxn];//记录最终选得是哪些点 int tt[maxn];//记录中间过程选得是哪些点 int vis[maxn]; int low[maxn]; double minn; int Prim(int s) { int sum=0; memset(vis,0,sizeof(vis)); for(int i = 1; i <= m; i++) { low[tt[i]] = e_val[s][tt[i]]; } vis[s] = 1; low[s] = 0; int pos = s; for(int i = 1; i < m; i++) { int min_t = INF; for(int j = 1; j <= m; j++) { if(!vis[tt[j]] && min_t > low[tt[j]]) { min_t = low[tt[j]]; pos = tt[j]; } } vis[pos] = 1; sum += min_t; for(int j = 1; j <= m; j++) { if(!vis[tt[j]] && e_val[pos][tt[j]] < low[tt[j]]) low[tt[j]]=e_val[pos][tt[j]]; } } return sum; } void DFS(int n_pre, int k) { if(k == m) { double n_sum = 0; for(int i = 1; i <= m ; i++) { n_sum+=node[tt[i]]; } double e_ans = 0; e_ans = Prim(tt[1]); double ans = e_ans/(n_sum*1.0); //if(ans < minn) if(ans - minn < -(eps)) { minn = ans; for(int i = 1; i <= m; i++) { ansn[i] = tt[i]; } } return ; } for(int i = n_pre+1; i <= n; i++) { tt[k+1] = i; DFS(i,k+1); } } int main() { while(~scanf("%d%d",&n,&m)) { if(n==0 && m==0) break; minn = INF; 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",&e_val[i][j]); } } for(int i = 1; i <= n; i++) { tt[1] = i; DFS(i, 1); } for(int i = 1; i < m; i++) { printf("%d ",ansn[i]); } printf("%d\n",ansn[m]); } return 0; }
HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。