hdu 2489 最小生成树

来源:互联网 发布:linux ip 编辑:程序博客网 时间:2024/05/17 18:03
//hdu 2489/*利用dfs枚举m个点在找最小生成树*/#include <stdio.h>#include <string.h>int node[20];int edge[20][20];int m, n;int visNod[20];int minNod[20];double ratio = 1000000000.0;//最小生成树//划分两个集合A,B,每次从集合A中选一条到集合B中节点的最小边,并加入到集合A中,直至集合B空double mst(int *t){    //边的权值和, k为已加入到集合中节点的个数    int val = 0, k=0, nn=0, minEdge = 1000000000;    int cn = t[19];    int A[20],B[20];    //初始化集合A,B    for(int i=0; i<n; i++)    {        B[i] = t[i];        A[i] = 0;    }    A[cn] = 1; B[cn] = 0;    while(++k<m)    {        minEdge = 1000000000;        for(int i=0; i<n; i++)        {            if(A[i]) cn = i;            else continue ;            for(int j=0; j<n; j++)            {                if(B[j] && cn!=j && edge[cn][j]<minEdge)                {                    nn = j;                    minEdge = edge[cn][j];                }            }        }        B[nn] = 0;        A[nn] = 1;        val += minEdge;    }    return val*1.0/t[18];}//ct表示当前访问的节点void dfs(int ct, int deepth){    //找到了m个节点,开始找最小生成树    if(deepth==m)    {        int temp[20] = {0};        for(int i=0; i<n; i++)        {            if(visNod[i])            {                temp[18] += node[i];                if(!temp[19]) temp[19] = i;            }            temp[i] = visNod[i];        }        double t = mst(temp);        if(ratio>t)        {            ratio = t;            for(int i=0; i<n; i++)            {                minNod[i] = visNod[i];            }        }        return ;    }    //没有更多的点了,枚举已完成    if(ct>n) return ;    for(int i=ct+1; i<n; i++)    {        visNod[i] = 1;        dfs(i, deepth+1);        visNod[i] = 0;    }}int main(){    while(scanf("%d %d", &n, &m))    {        if(!m && !n) break ;        memset(visNod, 0, sizeof(visNod));        ratio = 1000000.0;        for(int i=0; i<n; i++)        {            scanf("%d", node+i);        }        for(int i=0; i<n; i++)        {            for(int j=0; j<n; j++)            {                scanf("%d", *(edge+i)+j);            }        }        for(int i=0; i<n; i++)        {            visNod[i] = 1;            dfs(i, 1);            visNod[i] = 0;        }        for(int i=0, j=0; i<n; i++)        {            if(minNod[i])            {                if(++j<m) printf("%d ", i+1);                else printf("%d", i+1);            }        }        printf("\n");    }    return 0;}/*5 41 1 1 1 10 1 2 2 21 0 2 2 22 2 0 2 22 2 2 0 12 2 2 1 02 21 10 22 0*/

0 0