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. 从库函数操作RCC的流程来理解偏移变量

    下面是库函数操作RCC流程,看完后有我的疑问:偏移地址的理解 1,库函数直接操作:RCC库函数操作  RCC_APB2PeriphClockCmd ()RCC->APB2ENR |= RCC_A ...

  2. android apk瘦身之 图片压缩 tinypng

    参考地址: http://blog.csdn.net/jy692405180/article/details/52409369 http://www.tuicool.com/articles/BraI ...

  3. android 布局preview 技巧

    最近开始看老外写的文章,博客,嗯,不能说比国人写的好,但是感觉看着很爽.真的,一手资料就是爽. 嗯,自己做得不错,第一次看外文博客,我知道自己怎么看的,一句话一句话看下来的,越看越有感觉. 下面这个 ...

  4. android stadio svn 使用技巧

    有时候有这样的需求: 就是我一次要改很多的需求,然后代码要分开提交,那么怎么办? 提交的时候一个一个的点开看? 比如:这次改的还没有提上去,又来了一个需求,怎么区分呢 新建一个active的变化列表 ...

  5. samba server on Mac OS X Lion Server

    一般Mac共享通过配置wins,smb即可实现.注意在同一个工作组! 参考:http://computers.tutsplus.com/tutorials/how-to-set-up-an-smb-s ...

  6. groupSum6后向遍历

    http://codingbat.com/prob/p199368 public boolean groupSum6(int start, int[] nums, int target) { if( ...

  7. 剑指Offer - 九度1362 - 左旋转字符串(Move!Move!!Move!!!)

    剑指Offer - 九度1362 - 左旋转字符串(Move!Move!!Move!!!)2013-11-23 03:05 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任 ...

  8. Http状态码枚举(摘自 Microsoft 程序集 System.dll)

    // 摘要: // 包含为 HTTP 定义的状态代码的值. public enum HttpStatusCode { // 摘要: // 等效于 HTTP 状态 100. System.Net.Htt ...

  9. PhpStorm快捷键设置/个性化设置,如何多项目共存?如何更换主题?

    #常用快捷键  设置快捷键:File -> Settings -> IDE Settings -> Keymap -> 选择“Eclipse” -> 然后“Copy”一份 ...

  10. linux configuration

    sudo vi /etc/profile export JAVA_HOME=/usr/bin/jdk1.8.0_40export JRE_HOME=${JAVA_HOME}/jre  export C ...