HDU ACM 2489 Minimal Ratio Tree

来源:互联网 发布:诸神黄昏灵羽进阶数据 编辑:程序博客网 时间:2024/04/28 02:50
Minimal Ratio TreeTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3057    Accepted Submission(s): 917


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 230 20 100 6 26 0 32 3 02 21 10 22 00 0
 

Sample Output
1 31 2
 

Source
枚举n个顶点中所有个m个顶点的最小生成树,选出一个比率最小的即可Prim算法。注意至少要深搜1-——n-m+1个结点,才能确保遍历所有组合
#include<iostream>#include<string.h>using namespace std;const int INF=0x1f1f1f1f;int edge[20][20];int node[20];bool flag[20];bool f1[20];double res;int dfs_cnt;bool arr[20];int n,m;int mst(){    int ret=0;    int low[20]={0};    int sta;    for(int i=1;i<=n;i++)    {        if(f1[i])        {            sta=i;            break;        }    }    low[sta]=0;    flag[sta]=1;    for(int i=1;i<=n;i++)    {        if(f1[i])        {            low[i]=edge[sta][i];        }    }    for(int i=1;i<m;i++)    {        int Min=INF;        int loc;        for(int j=1;j<=n;j++)        {            if(f1[j]&&!flag[j]&&low[j]<Min)            {                Min=low[j];                loc=j;            }        }        flag[loc]=1;        ret+=low[loc];        for(int j=1;j<=n;j++)        {            if(f1[j]&&!flag[j])            {                if(edge[loc][j]<low[j])                {                    low[j]=edge[loc][j];                }            }        }    }    return ret;}void dfs(int v){    f1[v]=1;    dfs_cnt++;    if(dfs_cnt==m)    {        memset(flag,0,sizeof(flag));        int r=mst();        int sum=0;        for(int i=1;i<=n;i++)        {            if(f1[i])            {                sum+=node[i];            }        }        double ans=double(r)/double(sum);        if(ans-res<-(1e-9))        {          memcpy(arr,f1,sizeof(f1));          res=ans;        }        f1[v]=0;        dfs_cnt--;        return ;    }    for(int i=v+1;i<=n;i++)    {        dfs(i);    }    f1[v]=0;    dfs_cnt--;}int main(){    while(cin>>n>>m,n+m)    {        for(int i=1;i<=n;i++)            cin>>node[i];        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)                cin>>edge[i][j];        }        res=double (INF);        for(int i=1;i<=n-m+1;i++)        {            memset(f1,0,sizeof(f1));            dfs_cnt=0;            dfs(i);        }        int fir=1;        for(int i=1;i<=n;i++)        {            if(arr[i])            {                if(fir)                {                    fir=0;                    cout<<i;                }                else                    cout<<" "<<i;            }        }        cout<<endl;    }    return 0;}

0 0
原创粉丝点击