UVA 11183 (最小树形图)

一道最小树形图模板题,学习了一下

http://hi.baidu.com/lydrainbowcat/item/5fbae3fb9c159c5ec8f33753

以下转自该博客:

题目大意:给定一个有向图,根节点已知,求该有向图的最小树形图。最小树形图即有向图的最小生成树,定义为:选择一些边,使得根节点能够到达图中所有的节点,并使得选出的边的边权和最小。

题目算法:朱-刘算法(即由中国人朱永津和刘振宏共同发明的算法)。

算法步骤如下:(本文不再证明,参考下面给出的我自己画的一个图即可理解)

1.判断图的连通性,若不连通直接无解,否则一定有解。

2.为除了根节点以外的所有点选择一个权值最小的入边,假设用pre数组记录前驱,f数组记录选择的边长,记所选边权和为temp。

3.(可利用并查集)判断选择的的边是否构成环,若没有则直接ans+=temp并输出ans,若有,则进行下一步操作。

4.对该环实施缩点操作,设该环上有点V1,V2……Vi……Vn,缩成的点为node ,对于所有不在环中的点P进行如下更改:

(1) 点P到node的距离为min{a[p,Vi]-f[Vi]} (a为边集数组)

 (2)点node到p的距离为min{a[Vi,p]}

操作(1)的理解:先假设环上所有边均选上,若下次选择某一条边进入该环,则可以断开进入点与进入点的前驱之间的边,即断开F[进入点],所以等效为直接把a[p,node]赋值为min{a[p,Vi]-f[Vi]}。

特别提醒:本题有自环,可以提前删掉,因为它没有用。


#include
#include
#include
using namespace std;
const int maxn = 1005;
const int maxm = 40005;
const int inf = 0x3f3f3f3f;
struct node
{
    int from;
    int v;
    int len;
}edge[maxm];
int in[maxn],pre[maxn],id[maxn],vis[maxn];
int dir_mst(int root,int n,int m)
{
    int ans=0;
    while(1)
    {
        //先找出所有点的最小入边
        /*memset(in,inf,sizeof(in)); //这样写会报错!*/
        for(int i=0;i


你可能感兴趣的:(图论)