• Minimal Ratio Tree prime()&&枚举点


    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个点,组成最小生成树
    ***************************************************************************************************************************
      1 #include<iostream>
      2 #include<string>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<cstdio>
      6 using namespace std;
      7 int vis1[1001],vis2[1001],ans[1001];
      8 double e[1001][1001],p[1001],dis[1001],minRatio;
      9 int n,m,i,j;
     10 double prime()//求最小生成树
     11 {
     12     int u;
     13     memset(vis1,0,sizeof(vis1));
     14     int it,jt;
     15     u=0;
     16     while(!vis2[u]&&u<=n)u++;
     17     vis1[u]=1;
     18     double psum=0.0,esum=0.0;
     19     for(it=1;it<=n;it++)
     20     {
     21         if(vis2[it])
     22         {
     23             dis[it]=e[u][it];
     24             psum+=p[it];
     25         }
     26     }
     27     for(it=1;it<m;it++)
     28     {
     29         u=-1;
     30         for(jt=1;jt<=n;jt++)
     31         {
     32             if(vis2[jt]&&!vis1[jt])
     33                 if(u==-1||dis[jt]<dis[u])
     34                 {
     35                    u=jt;
     36                 }
     37 
     38         }
     39         esum+=dis[u];
     40         vis1[u]=1;
     41         for(jt=1;jt<=n;jt++)
     42         {
     43             if(!vis1[jt]&&vis2[jt])
     44               if(dis[jt]>e[u][jt])
     45                 dis[jt]=e[u][jt];
     46         }
     47     }
     48     return esum/psum;
     49 }
     50 void dfs(int u,int num)//枚举
     51 {
     52     if(num>m)return;
     53     if(u==n+1)
     54     {
     55         if(num!=m)return;
     56         double t=prime();
     57         //cout<<"T:: "<<t<<endl;
     58         if(t<minRatio)
     59         {
     60                 minRatio=t;
     61               memcpy(ans,vis2,sizeof(vis2));//记录
     62         }
     63         return;
     64     }
     65     vis2[u]=1;
     66     dfs(u+1,num+1);
     67     vis2[u]=0;
     68     dfs(u+1,num);
     69 
     70 }
     71 int main()
     72 {
     73     while(scanf("%d %d",&n,&m)!=EOF)
     74     {
     75         if(n==0&&m==0)
     76             break;
     77         for(i=1;i<=n;i++)
     78         {
     79             scanf("%lf",&p[i]);
     80             //printf("p::%lf
    ",p[i]);
     81         }
     82         for(i=1;i<=n;i++)
     83          for(j=1;j<=n;j++)
     84           {
     85             scanf("%lf",&e[i][j]);
     86           }
     87           minRatio=10000000.0;
     88           memset(vis2,0,sizeof(vis2));
     89           //memset(ans,0,sizeof(ans));
     90           dfs(1,0);
     91         bool gs=0;
     92           for(i=1;i<=n;i++)
     93           {
     94               if(ans[i])
     95                {
     96                    if(gs==0)
     97                    {
     98                        printf("%d",i);
     99                        gs=1;
    100                     }
    101                     else
    102                     {
    103                         printf(" %d",i);
    104                     }
    105                }
    106           }
    107          puts("");
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    reids 持久化
    center os 下redis安装以及基本使用
    MongoDB安装(Window)
    mysql中文乱码解决办法
    github托管代码
    MySQL表损坏修复【Incorrect key file for table】
    运维杂记-02
    配置ssh秘钥登陆
    nginx解决跨域问题
    运维杂记-01
  • 原文地址:https://www.cnblogs.com/sdau--codeants/p/3402073.html
Copyright © 2020-2023  润新知