码迷,mamicode.com
首页 > Web开发 > 详细

POJ3164 Command Network 最小树形图

时间:2016-05-10 20:32:58      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

最小树形图,就是给有向带权图中指定一个特殊的点root,求一棵以root为根的有向生成树T,并且T中所有边的总权值最小。

朱刘算法模板题

技术分享
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;
const int N=1e2+5;
const int INF=0x3f3f3f3f;
struct Node{
  double x,y;
}p[N];
struct Edge{
    int u,v;
    double w;
}edge[N*N];
double in[N];
int id[N],vis[N],pre[N],n,m;
double dis(int u,int v){
   double x=p[u].x-p[v].x,y=p[u].y-p[v].y;
   return sqrt(x*x+y*y); 
}
double zhuliu(int rt,int n,int m){
     double ret=0;
     while(1){
     for(int i=1;i<=n;++i)in[i]=INF;
     for(int i=1;i<=m;++i){
        if(edge[i].u!=edge[i].v&&edge[i].w<in[edge[i].v]){
            pre[edge[i].v]=edge[i].u;
            in[edge[i].v]=edge[i].w;
        }
     }
     for(int i=1;i<=n;++i)
     if(i!=rt&&in[i]==INF)return -1;
     int cnt=0;
     memset(id,-1,sizeof(id));
     memset(vis,-1,sizeof(vis));
     in[rt]=0;
     for(int i=1;i<=n;++i){
        ret+=in[i];
        int v=i;
        while(vis[v]!=i&&id[v]==-1&&v!=rt){
            vis[v]=i;
            v=pre[v];
        }
        if(v!=rt&&id[v]==-1){
            ++cnt;
            for(int u=pre[v];u!=v;u=pre[u])
              id[u]=cnt;
            id[v]=cnt;
        }
     }
     if(cnt==0)break;
     for(int i=1;i<=n;++i)
     if(id[i]==-1)id[i]=++cnt;
     for(int i=1;i<=m;++i){
        int u=edge[i].u,v=edge[i].v;
        edge[i].u=id[u];
        edge[i].v=id[v];
        if(id[u]!=id[v])edge[i].w-=in[v];
     }
     n=cnt;
     rt=id[rt];
     }
     return ret;   
}
int main()
{
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;++i)scanf("%lf%lf",&p[i].x,&p[i].y);
        for(int i=1;i<=m;++i){
          scanf("%d%d",&edge[i].u,&edge[i].v);
          edge[i].w=INF;
          if(edge[i].u!=edge[i].v)edge[i].w=dis(edge[i].u,edge[i].v);
        }
        double ans=zhuliu(1,n,m);
        if(ans<0)printf("poor snoopy\n");
        else printf("%.2f\n",ans);    
    }
    return 0;
}
View Code

 

POJ3164 Command Network 最小树形图

标签:

原文地址:http://www.cnblogs.com/shuguangzw/p/5478859.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!