zoukankan      html  css  js  c++  java
  • hdu 2489 dfs枚举组合情况+最小生成树

      大家都说,搜索是算法的基础。今天最这题就有体会了。在n个顶点里选择m个顶点,求最小生成树。用到了深搜的回溯。所有情况都能枚举。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=20,INF=0x3f3f3f3f;
    int dist[N],Map[N][N],pre[N];
    //向外延伸的最短边长,记录图信息,记录连接信息
    bool p[N];//1表示点已经在树的,0表示点在树外
    bool f[N][N];
    int  Prim(int n)
    {
        int i,j,k,Min,ans=0;
        for(i=2;i<=n;i++)
        {
            p[i]=0;
            dist[i]=Map[1][i];
            pre[i]=1;
        }
        dist[1]=0;
        p[1]=1;
        for(i=1;i<n;i++)
        {
            Min=INF;
            k=0;
            for(j=1;j<=n;j++)
            {
                if(!p[j]&&dist[j]<Min)
                {
                    Min=dist[j];
                    k=j;
                }
            }
            if(k==0) return -1;//G不连通
            p[k]=1;
            ans+=Min;
            for(j=1;j<=n;j++)
            {
                if(!p[j]&&Map[k][j]!=INF&&dist[j]>Map[k][j])
                {
                    dist[j]=Map[k][j];
                    pre[j]=k;
                }
            }
        }
        return ans;
    }
    
    int nd[N],mat[N][N],cs[N],vb[N];
    bool vis[N];
    int num, node, edge;
    void dfs(int x, int m,int n)
    {
        int i,j,k;
        if(num==m)
        {
            int s=0;
            for(i=1;i<=m;i++)
                s+=nd[cs[i]];
            for(i=1;i<=m;i++)
                for(j=1;j<=m;j++)
                    Map[i][j]=mat[cs[i]][cs[j]];
            int ans=Prim(m);
            if(ans==-1) return ;
            if(ans*node < s*edge)//两个分式的比较,变为乘积比较
            {
                node =s;
                edge=ans;
                for(i=1;i<=m;i++)
                    vb[i]=cs[i];
            }
            return ;
        }
        for(i=x+1;i<=n;i++)
        {
            if(!vis[i])
            {
                num++;
                vis[i]=1;
                cs[num]=i;
                dfs(i,m,n);
                vis[i]=0;
                --num;
            }
        }
    }
    void init()
    {
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                mat[i][j]=INF;
    }
    int main()
    {
        //freopen("test.txt","r",stdin);
        int n,m,i,j,k;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(!n) break;
            init();
            for(i=1;i<=n;i++)
                scanf("%d",&nd[i]);
            for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)
                    scanf("%d",&mat[i][j]);
            node=1; edge=1000000;
            for(i=1;i<=n-m+1;i++)
            {
                memset(vis,0,sizeof(vis));
                vis[i]=1;
                num=1;
                cs[num]=i;
                dfs(i,m,n);
            }
            for(i=1;i<m;i++)
                printf("%d ",vb[i]);
            printf("%d
    ",vb[i]);
        }
        return 0;
    }
  • 相关阅读:
    IDEA 使用镜像快速创建SpringBoot项目
    ajax基础学习笔记
    GitHub高效搜索
    MVC收藏的实现
    一个显示界面
    R-MS
    MS-API。AJAS
    MS-MVCAJAS 秒杀的添加功能吧
    真-API控制器AJAS
    真-API.DALBLL.AJAS/// 添加/// 绑定分类/// 显示,查询/// 删除//删除/// 反填/// 修改
  • 原文地址:https://www.cnblogs.com/Potato-lover/p/3937094.html
Copyright © 2011-2022 走看看