HDU 2489 Prim+DFS

因为是完全图,所以可以采用如下的方式进行DFS搜索,枚举出每一种情况,然后用Prim进行计算。

#include<cstdio>
#include<cstring>
#define N 20
int n,m,vis[N], ans[N], pre[N], hash[N];
double G[N][N], weight[N], minCost[N], minRatio;


double prim(){
    memset(hash, 0, sizeof(hash));
    int u;
    for(int i=1; i<=n; ++i)if(vis[i]){
        u=i; break;
    }
    hash[u] = 1;
    double weightSum=0, edgeSum=0;
    for(int i=1; i<=n; ++i)if(vis[i]){
        minCost[i] = G[u][i]; pre[i] = u;
        weightSum += weight[i];
    }

    for(int i=1; i<m; ++i){
        u=-1;
        for(int j=1; j<=n; ++j)if(vis[j]&&!hash[j]){
            if(u==-1 || minCost[u]>minCost[j])
                u=j;
        }
        edgeSum += G[pre[u]][u];
        hash[u] = 1;
        for(int j=1; j<=n; ++j)if(vis[j]&&!hash[j]){
            if(minCost[j] > G[u][j]){
                minCost[j] = G[u][j];
                pre[j] = u;
            }
        }
    }
   return edgeSum/weightSum;
}


void dfs(int u, int num){
    if(num>m) return; 
    if(u==n+1){
        if(num!=m) return;
        double t=prim();
        if(t<minRatio){
            minRatio = t;
            memcpy(ans, vis, sizeof(vis));
        }
        return;
    }
    vis[u] = 1;
    dfs(u+1, num+1);
    vis[u] = 0;
    dfs(u+1, num);
}

int main(){
    while(~scanf("%d%d",&n,&m)){
        if(!n&&!m) break; 
        for(int i=1; i<=n; ++i) 
            scanf("%lf",&weight[i]);
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
                scanf("%lf",&G[i][j]);
        memset(vis, 0, sizeof(vis));
        minRatio = 100000000;
        dfs(1, 0);
        bool flag=false;
        for(int i=1; i<=n; ++i)if(ans[i]){
            if(flag) printf(" %d", i);
            else { printf("%d",i); flag=true; }
        }
        puts("");
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值