Minimal Ratio Tree (hdu 2489 dfs+最小生成树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2489

dfs出每种排列组合情况

然后最小生成树

easy的

#include<bits/stdc++.h>
using namespace std;
int a[19];
int n,m,mp[19][19];
int b[19];
struct node
{
    int x,y,s;
}ydw[1900];
int jg[19];
double minn=1e9;
bool cmp(node a,node b)
{
    return a.s<b.s;
}
int p[19];
int findd(int x)
{
    return x==p[x]?x:p[x]=findd(p[x]);
}
void join(int x,int y)
{
    x=findd(x);
    y=findd(y);
    if(x!=y)p[y]=x;
}
double  prim(int *b)
{
    int kk=0;
    for(int i=0;i<=n;i++)p[i]=i;//注意到n
    for(int j=0;j<m;j++)
    {
        for(int i=j+1;i<m;i++)
        {
            ydw[kk].x=b[j];
            ydw[kk].y=b[i];
            ydw[kk++].s=mp[b[i]][b[j]];
        }
    }
    sort(ydw,ydw+kk,cmp);
    int sum=0;
    for(int i=0;i<kk;i++)
    {
        if(findd(ydw[i].x)!=findd(ydw[i].y))
        {
            join(ydw[i].x,ydw[i].y);
            sum+=ydw[i].s;
        }
    }
    int sumd=0;
    for(int i=0;i<m;i++) sumd+=a[b[i]];
    return sum*1.0/sumd;//一开始直接return sum了
}
void dfs(int k,int ans)
{
    if(ans==m)
    {
        double ss=prim(b);
        if(ss<minn)
        {
            for(int i=0;i<m;i++) jg[i]=b[i];
            minn=ss;
        }
    }
    for(int i=k+1;i<=n;i++)
    {
        b[ans]=i;
        dfs(i,ans+1);
    }
}
int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m),n||m)
    {
        memset(jg,0,sizeof(jg));
        minn=1e9;
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&mp[i][j]);
            }
        }
        dfs(0,0);
        for(i=0;i<m;i++)
        {
            if(i==0)cout<<jg[i];
            else cout<<" "<<jg[i];
        }
        cout<<endl;
    }
    return 0;
}

 

posted @ 2019-08-14 14:59  -第4题-  阅读(134)  评论(0编辑  收藏  举报