zoukankan      html  css  js  c++  java
  • HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

    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;
    }
  • 相关阅读:
    java 随机流
    java 缓冲流
    java 文件字符输入、输出流
    【JMeter4.0】之 “jdk1.8、JMeter4.0” 安装与配置以及JMeter永久汉化和更改界面背景、并附加附录:个人学习总结
    【Selenium + Python】自动化测试之发送邮件正文以及附件同时发送
    【Mysql】之视图操作
    【Mysql】Navicat For Mysql快捷键
    【Axure插件】之浏览器打开失败
    【Mysql】之基础sql语句模板
    C语言中malloc、free和new、delete的用法和区别
  • 原文地址:https://www.cnblogs.com/stepping/p/5723095.html
Copyright © 2011-2022 走看看