• poj 3164 最小树形图


    思路:就是裸的最小树形图~

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define Maxn 110
    #define LL double
    #define inf 1e9
    using namespace std;
    int pre[Maxn],id[Maxn],vi[Maxn],num;
    LL in[Maxn];
    struct Edge{
        int u,v;
         LL val;
    }edge[Maxn*Maxn];
    struct Point{
        double x,y;
    }p[Maxn];
    double Dis(Point a,Point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    void add(int u,int v,LL val)
    {
        edge[num].u=u,edge[num].v=v,edge[num++].val=val;
    }
    LL directed_MST(int root,int n,int e)
    {
        int i,j,u,v,cnt=0;
        LL ans=0;
        while(1)
        {
            for(i=1;i<=n;i++) in[i]=inf;
            for(i=0;i<e;i++)//找最小入边
            {
                u=edge[i].u;
                v=edge[i].v;
                if(in[v]>edge[i].val&&v!=u)
                {
                    in[v]=edge[i].val;
                    pre[v]=u;
                }
            }
            for(i=1;i<=n;i++)
            {
                if(i==root) continue;
                if(in[i]==inf) return -1;
            }
            memset(vi,-1,sizeof(vi));
            memset(id,-1,sizeof(id));
            cnt=0;
            in[root]=0;
            for(i=1;i<=n;i++)//枚举每个可能是环上的点
            {
                ans+=in[i];
                v=i;
                while(vi[v]!=i&&id[v]==-1&&v!=root)
                {
                    vi[v]=i;v=pre[v];
                }
                if(v!=root&&id[v]==-1)//如果退出上个循环的条件不是v==root,就是vi[i]==i,即找到了环
                {
                    id[v]=++cnt;
                    for(u=pre[v];u!=v;u=pre[u])//对环进行统一标号
                        id[u]=cnt;
                }
            }
            if(cnt==0) break;//无环 ,退出
            for(i=1;i<=n;i++) if(id[i]==-1) id[i]=++cnt;
            for(i=0;i<e;i++)//进行缩点,并修改每条边的权值。
            {
                v=edge[i].v;
                edge[i].u=id[edge[i].u];
                edge[i].v=id[edge[i].v];
                if(edge[i].u!=edge[i].v)
                    edge[i].val-=in[v];
            }
            n=cnt;
            root=id[root];
        }
        return ans;
    }
    int main()
    {
        int i,j,n,m,a,b;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            num=0;
            for(i=1;i<=n;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&a,&b);
                if(a!=b)
                add(a,b,Dis(p[a],p[b]));
            }
            double ans=directed_MST(1,n,num);
            if(ans==-1)
                printf("poor snoopy
    ");
            else
                printf("%.2lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    《浪潮之巅》笔记之五
    《浪潮之巅》笔记之四
    《浪潮之巅》笔记之三
    《浪潮之巅》笔记之二
    《浪潮之巅》笔记之一
    basename、dirname、alias、date
    grep命令
    centos6下通用二进制格式安装MySQL过程
    在centos6中编译安装httpd-2.4/搭建LAMP
    在服务器端对sshd做白名单
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3214719.html
Copyright © 2020-2023  润新知