poj 1639 Picnic Planning 最小k度生成树

题目:点击打开链接

题意:

就是求最小限度生成树,不会做,我是参考这篇http://www.cnblogs.com/jackge/archive/2013/05/12/3073669.html博客做的

分析:

要求最小 k 度生成树,我们可以按照下面的步骤来做:

设有度限制的点为 V0 ,V0称为根节点

1,把所有与 V0 相连的边删去,图会分成多个子图(假设为 m 个,显然的,如果 m > k,那么问题无解),让他们分别求最小生成树;然后用最小的代价将 m 个最小生成树和 V0 连起来,那我们就得到了一棵关于 V0 的最小 m 度生成树。

2,在 m 度生成树中找一个点和 V0 相连(设这条边的权值为 a),会生成一个环,为了满足最小生成树的要求,我们必须删掉一条边(设这条边的权值为 b),以使总权值尽量小,那么就要求 a 尽量的小,b 尽量的大。

完成一次 2 的操作后得到的是 m+1 度最小生成树,以此类推,直到得到最小 k 度生成树。


#include 
#include
#include
#include
#include
#include
using namespace std;
const int INF=0x3f3f3f3f;
const int N=30;
struct node
{
    int v,cap;
    node(){}
    node(int v,int cap):v(v),cap(cap){}
    bool operator <(const node &a)const{
        return a.capmp;
int g[N][N],dis[N],col[N],pre[N],fst[N],maxside[N];
int n,m,k;
int Prim(int src,int id)
{
    priority_queueq;
    while(!q.empty())q.pop();
    dis[src]=0;
    q.push(node(src,0));
    int ans=0;
    while(!q.empty()){
        node cur=q.top();
        q.pop();
        int u=cur.v;
        if(!col[u]){
            col[u]=id;
            ans+=dis[u];
            for(int i=1;ig[u][i]){
                    pre[i]=u;
                    dis[i]=g[u][i];
                    q.push(node(i,dis[i]));
                }
            }
        }
    }
    return ans;

}
void update(int cur,int last,int max_side)
{
    maxside[cur]=max_side>g[cur][last]?max_side:g[cur][last];
    for(int i=1;icap)g[u][v]=g[v][u]=cap;
        }
        scanf("%d",&k);
        solve();
    }
    return 0;
}


你可能感兴趣的:(最小生成树)