zoukankan      html  css  js  c++  java
  • POJ3164 Command Network 最小树形图

    最小树形图,就是给有向带权图中指定一个特殊的点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
    ");
            else printf("%.2f
    ",ans);    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    unity3d应用内分享(微信、微博等)的实现
    Cocostudio 文章列表
    C++ 文章列表
    Android 文章列表
    js函数节流和函数防抖
    js实现队列-通过闭包方式
    初学js正则
    Android网络图片加载
    利用html5制作正方体,同时实现3D旋转效果
    Python模块——random随机模块
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5478859.html
Copyright © 2011-2022 走看看