zoukankan      html  css  js  c++  java
  • CSU 1116 Kingdoms 最小生成树(prim)

    由于点数只有16,而点1又必选,暴力枚举选点情况,每次做一个最小生成树

    这里用的prim算法,要注意的是存在选取这些点但找不到生成树的情况,需要将之排出

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<map>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=18;
    int mp[maxn][maxn];
    int wi[maxn];
    bool vis[maxn];
    int prim(int n)
    {
        int low[maxn];
        int ans=0,i,j;
        for(i=1;i<=n;i++)
            if(!vis[i])
                low[i]=mp[1][i];
            else
                low[i]=0;
        for(i=2;i<=n;i++)
        {
            int mi=INF,idx;
            for(j=2;j<=n;j++)
                if(!vis[j]&&low[j]<mi)
                {
                    mi=low[j];
                    idx=j;
                }
            if(mi==INF)    break;
            ans+=mi;
            vis[idx]=true;
            for(j=2;j<=n;j++)
                if(!vis[j]&&low[j]>mp[idx][j])
                    low[j]=mp[idx][j];
        }
        for(i=2;i<=n;i++)
            if(!vis[i])    return INF;
        return ans;
    }
    int main()
    {
        int i,j,n,m,k,t,u,v,w;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&k);
            memset(mp,INF,sizeof(mp));
            for(i=1;i<=n;i++)
            {
                scanf("%d",&wi[i]);
                mp[i][i]=0;
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                if(mp[u][v]>w)
                mp[u][v]=mp[v][u]=w;
            }
            int len=(1<<(n-1))-1;
            int ans=0;
            for(i=0;i<=len;i++)
            {
                int x=i;
                int sum=0;
                for(j=n;j>=2;j--)
                {
                    if(x&1)    
                        vis[j]=true;
                    else
                    {
                        sum+=wi[j];
                        vis[j]=false;
                    }
                    x>>=1;
                }
                vis[1]=false;sum+=wi[1];
                int sk=prim(n);
                if(sk<=k&&sum>ans)    ans=sum;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    POJ 1228 Grandpa's Estate | 凸包
    POJ 2187 Beauty Contest | 旋转卡壳
    POJ 3348 Cows | 凸包模板题
    POJ 1375 Intervals | 解析几何
    POJ 2074 | 线段相交
    POJ 1039 Pipe | 线段相交
    POJ 3304 Segments | 线段相交
    POJ 2318 TOYS | 二分+判断点在多边形内
    jpg、jpeg、png... 的区别
    xhr.readyState就绪状态
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/4758945.html
Copyright © 2011-2022 走看看