HDU 2489 Prim+DFS

来源:互联网 发布:微分销源码 编辑:程序博客网 时间:2024/06/17 08:30

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

#include<cstdio>#include<cstring>#define N 20int 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;}