码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

时间:2016-07-31 15:46:29      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

Minimal Ratio Tree

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 12   Accepted Submission(s) : 7

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

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<cstdio>
#include<cstring>
#include<climits>
using namespace std;

int a[20],f[20],p[20];
int mp[20][20];
bool vis[20];
int i,j,n,m;
double ans;
void prim() //最小生成树
{
    bool vis[20];
    int dis[20];
    int sumnode,sumedge=0,k;
    memset(vis,0,sizeof(vis));
    vis[1]=1;
    sumnode=p[a[1]];
    for(int i=1;i<=m;i++) dis[i]=mp[a[1]][a[i]];
    for(int i=1;i<m;i++)
    {
        int minn=INT_MAX;
        for(int j=1;j<=m;j++)
        {
            if (!vis[j] && dis[j]<minn)
            {
                minn=dis[j];
                k=j;
            }
        }
            vis[k]=1;
            sumedge+=minn;
            sumnode+=p[a[k]];
            for(int j=1;j<=m;j++)
                if (!vis[j] && dis[j]>mp[a[k]][a[j]])
                        dis[j]=mp[a[k]][a[j]];
    }
    double w=sumedge*1.0/sumnode;
    if (w<ans)  //把最优解存放在f数组中
    {
        ans=w;
        for(int i=1;i<=m;i++)
            f[i]=a[i];
    }
  return;
}
void dfs(int k,int num)//dfs暴力枚举m个节点是哪几个存在a数组中
{
    if (num==m)
    {
        prim();
        return;
    }
    if (k>n) return;

    if (!vis[k])
    {
        vis[k]=1;
        a[num+1]=k;
        dfs(k+1,num+1);
        vis[k]=0;
    }
    dfs(k+1,num);
    return;
}
int main()
{
    while(scanf("%d%d",&n,&m))
    {
        if (n==0 && m==0) break;
        for(i=1;i<=n;i++) scanf("%d",&p[i]);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
               scanf("%d",&mp[i][j]);
        memset(vis,0,sizeof(vis));
        ans=INT_MAX*1.0;
        dfs(1,0);
        for(i=1;i<m;i++) printf("%d ",f[i]);
        printf("%d\n",f[m]);
    }
    return 0;
}

 

HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

标签:

原文地址:http://www.cnblogs.com/stepping/p/5723095.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!