Minimal Ratio Tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3899    Accepted Submission(s): 1196

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
题意:在n个点中选m个点出来,求使上面的公式最小的m个点的组合。
题解:点比较少,状压31MS。。先用状态压缩选择m个点出来,然后再对选出来的点进行公式的计算。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int N = ;
const int INF = ;
int graph[N][N];
int weight[N];
int state[<<N];
int a[N],result[N];;
int n,m;
int vis[N],low[N];
void input(){
for(int i=;i<=n;i++) scanf("%d",&weight[i]);
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
scanf("%d",&graph[i][j]);
}
}
}
bool check(int num){
int cnt =;
while(num){
if(num&) cnt++;
num = num>>;
}
if(cnt==m) return true;
return false;
}
void init(int &k){
for(int i=;i<(<<n);i++){
if(check(i)) state[k++]=i;
}
k--;
}
int prim(int n,int pos){
memset(vis,,sizeof(vis));
for(int i=;i<n;i++){
low[a[i]] = graph[pos][a[i]];
}
vis[pos] = true;
int cost = ;
for(int i=;i<n;i++){
int Min = INF;
for(int j=;j<n;j++){
if(!vis[a[j]]&&low[a[j]]<Min){
pos = a[j];
Min = low[a[j]];
}
}
vis[pos] = true;
cost +=Min;
for(int j=;j<n;j++){
if(!vis[a[j]]&&low[a[j]]>graph[pos][a[j]]) low[a[j]] = graph[pos][a[j]];
}
}
return cost;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF,n+m){
int k=;
init(k);
int min_id=N;
double _ratio = INF*1.0;
input(); for(int i=;i<=k;i++){
int num = state[i];
int t =,V=;
for(int j=;j<n;j++){
if((num>>j)&){ ///这里代表第j+1个点要选进去
a[t++] = j+;
V += weight[j+];
}
}
int cost = prim(t,a[]);
double temp1 = cost*1.0/V;
if(temp1<_ratio){
_ratio = temp1;
for(int i=;i<t;i++) result[i] = a[i];
}
}
for(int i=;i<m-;i++){
printf("%d ",result[i]);
}
printf("%d\n",result[m-]);
}
}

hdu 2489(状态压缩+最小生成树)的更多相关文章

  1. HDU 1074 (状态压缩DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...

  2. hdu 4739(状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4739 思路:状态压缩. #include<iostream> #include<cs ...

  3. HDU 3341 状态压缩DP+AC自动机

    题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...

  4. hdu 2167(状态压缩基础题)

    题意:给你一个矩阵,让你在矩阵中找一些元素使它们加起来和最大,但是当你使用某一个元素时,那么这个元素周围的其它八个元素都不能取! 分析:这是一道比较基础的状态压缩题,也是我做的第三道状态压缩的题,但是 ...

  5. hdu 1565(状态压缩基础题)

    题意:容易理解. 分析:这是我做的状态压缩第二题,一开始超内存了,因为数组开大了,后来超时了,因为能够成立的状态就那么多,所以你应该先把它抽出来!!总的来说还是比较简单的!! 代码实现: #inclu ...

  6. HDU 2553 状态压缩

    N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. hdu 3006(状态压缩)

    The Number of set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. hdu 4033 状态压缩枚举

    /* 看别人的的思路 搜索搜不出来我太挫了 状态压缩枚举+好的位置 */ #include<stdio.h> #include<string.h> #define N 20 i ...

  9. hdu 2489(枚举 + 最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2489 思路:由于N, M的范围比较少,直接枚举所有的可能情况,然后求MST判断即可. #include ...

随机推荐

  1. Active Directory 域服务 (AD DS) 虚拟化

    TechNet 库 Windows Server Windows Server 2012 R2 和 Windows Server 2012 服务器角色和技术 Active Directory Acti ...

  2. 很全的 Python 面试题

    很全的 Python 面试题 Python语言特性 1 Python的函数参数传递 看两个例子:           Python   1 2 3 4 5 a = 1 def fun(a):      ...

  3. 风格指南--C++

    0.避免多重包含是学编程时基本的要求; 1. 前置声明是为了降低编译依赖,防止修改一个头文件引发多米诺效应; 2. 内联函数的合理使用可提高代码执行效率; 3. ‐inl.h 可提高代码可读性 (一般 ...

  4. json序列化datetime类型数据

    错误描述: import jsonimport datetime a = datetime.datetime.now()print(a) b = json.dumps(a)print(b) 如上代码, ...

  5. 查看Linux系统用户登录日志

    日志: /var/log/wtmp说明: 此文件是二进制文件,查看方法如下:该日志文件永久记录每个用户登录.注销及系统的启动.停机的事件.因此随着系统正常运行时间的增加,该文件的大小也会越来越大,增加 ...

  6. (原)Unreal渲染模块 管线 - 着色器(1)

    @author: 白袍小道 转载悄悄说明下 随缘查看,施主开心就好 说明: 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RH ...

  7. (原)Unreal渲染模块 源码和实例分析说明

    @author:白袍小道 说明 1.由于小道就三境武夫而已,而UE渲染部分不仅管理挺大,而且牵扯技术和内容驳杂,所以才有这篇梳理. 2.尽量会按书籍和资料,源码,小模块的调试和搬山(就是敲键盘)..等 ...

  8. HDU 3642 Get The Treasury ( 线段树 求长方体体积并 )

    求覆盖三次及其以上的长方体体积并. 这题跟 http://wenku.baidu.com/view/d6f309eb81c758f5f61f6722.html 这里讲的长方体体积并并不一样. 因为本题 ...

  9. rxjs的世界

    rxjs学习了几个月了,看了大量的东西,在理解Observable的本文借鉴的是渔夫的故事,原文,知识的主线以<深入浅出rxjs>为主,动图借鉴了rxjs中文社区翻译的文章和国外的一个动图 ...

  10. 【bzoj4819】[Sdoi2017]新生舞会 分数规划+费用流

    题目描述 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个 ...