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. loj2472 「九省联考 2018」IIIDX

    ref #include <algorithm> #include <iostream> #include <cstdio> using namespace std ...

  2. 怎么设置才能让外网ip可以访问mysql数据库[转]

    转自: http://www.hongyanliren.com/89.html 使用mysql中,很多人都会遇到这样的问题:在vps服务器或者云服务器上安装了mysql后,使用其他工具在外网ip之下根 ...

  3. Visual Studio使用技巧笔记(引用程序集自动复制dll到引用项目目录)

    copy /y $(TargetPath) $(SolutionDir)\[您项目引用dll文件的目录]\$(TargetFileName) 例如:copy /y $(TargetPath) $(So ...

  4. java中继承的概念

    继承是类的三大特性之一,是java中实现代码重用的重要手段之一.       java中只支持单继承,即每个类只能有一个父类.       继承表达的是is a的关系,或者说一种特殊和一般的关系.   ...

  5. freemaker参考地址

    https://zhidao.baidu.com/question/1304215193023416939.html

  6. 孤荷凌寒自学python第十六天python的迭代对象

    孤荷凌寒自学python第十六天python的迭代对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 迭代也就是循环. python中的迭代对象有相关的如下几个术语: A容器 contrai ...

  7. easyUI tree jQuery

    Tree 数据转换 所有节点都包含以下属性: id:节点id,这个很重要到加载远程服务器数据 which is important to load remote data text: 显示的节点文本 ...

  8. [C语言]防止头文件和全局变量重复定义

      昨天下午将全局变量定义在H文件中导致链接时提示变量在多个obj文件内重复. 解决办法如下: 将变量移入C文件中进行定义,然后在H文件中加入extern在变量之前. 这样当其它C文件引用该全局变量时 ...

  9. [CF999E]Reachability from the Capital

    题目大意:有一个$n$个点$m$条边的有向图,起点$S$,要求你添加最少的边使得$S$可以到达所有点 题解:缩点,答案就是没有入边的强连通分量个数,注意,如果起点$S$所在的强连通块没有入边则不计入答 ...

  10. hdu 2829 斜率DP

    思路:dp[i][x]=dp[j][x-1]+val[i]-val[j]-sum[j]*sum[i]+sum[j]*sum[j]; 其中val[i]表示1~~i是一段的权值. 然后就是普通斜率dp做法 ...