zoukankan      html  css  js  c++  java
  • hdu4009最小树形图

    多建一个根,连到每一个点,然后花费是建水井的钱

    然后跑一边最小树形图即可,这题必定有解,因为可以从根开始到每一点,可以不用判无解的情况

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pi acos(-1)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define MIN(a,b) a<b ? a:b
    
    using namespace std;
    
    const double g=10.0,eps=1e-9;
    const int N=1000+10,maxn=500000+10,inf=0x3f3f3f3f;
    
    struct edge{
        int u,v,w;
    }e[maxn];
    struct pe{
        int x,y,z;
    }p[N];
    int pre[N],in[N],vis[N];
    int ans,Hash[N];
    int dis(int a,int b)
    {
        return abs(p[a].x-p[b].x)+abs(p[a].y-p[b].y)+abs(p[a].z-p[b].z);
    }
    bool dirmst(int root,int nv,int ne)
    {
        ans=0;
        while(1){
            memset(in,inf,sizeof in);
            for(int i=0;i<ne;i++)
            {
                int u=e[i].u,v=e[i].v;
                if(e[i].w<in[v]&&u!=v)
                {
                    in[v]=e[i].w;
                    pre[v]=u;
                }
            }
            in[root]=0;
            for(int i=0;i<nv;i++)
                if(in[i]==inf)
                   return 0;
            int cntnum=0;
            memset(vis,-1,sizeof vis);
            memset(Hash,-1,sizeof Hash);
            for(int i=0;i<nv;i++)
            {
                ans+=in[i];
                int v=i;
                while(vis[v]!=i&&v!=root&Hash[v]==-1)vis[v]=i,v=pre[v];
                if(v!=root&&Hash[v]==-1)
                {
                    for(int u=pre[v];u!=v;u=pre[u])
                        Hash[u]=cntnum;
                    Hash[v]=cntnum++;
                }
            }
            if(cntnum==0)return 1;
            for(int i=0;i<nv;i++)
                if(Hash[i]==-1)
                    Hash[i]=cntnum++;
            for(int i=0;i<ne;i++)
            {
                int v=e[i].v;
                e[i].v=Hash[e[i].v];
                e[i].u=Hash[e[i].u];
                if(e[i].v!=e[i].u)e[i].w-=in[v];
            }
            nv=cntnum;
            root=Hash[root];
        }
        return 1;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,x,y,z;
        while(cin>>n>>x>>y>>z){
            if(n==0&&x==0&&y==0&&z==0)break;
            for(int i=1;i<=n;i++)cin>>p[i].x>>p[i].y>>p[i].z;
            int cnt=0;
            for(int i=1;i<=n;i++)
            {
                int k,s;
                cin>>k;
                while(k--){
                    cin>>s;
                    e[cnt].u=i;
                    e[cnt].v=s;
                    e[cnt].w=dis(i,s)*y;
                    if(p[s].z>p[i].z)e[cnt].w+=z;
                    cnt++;
                }
            }
            for(int i=1;i<=n;i++)
            {
                e[cnt].u=0;
                e[cnt].v=i;
                e[cnt].w=x*p[i].z;
                cnt++;
            }
            dirmst(0,n+1,cnt))
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    树的直径
    Codeforces 734E Anton and Tree(缩点+树的直径)
    Codeforces 948D Perfect Security(字典树)
    Codeforces 954D Fight Against Traffic(BFS 最短路)
    Codeforces 954C Matrix Walk (思维)
    Codeforces 950D A Leapfrog in the Array (思维)
    Codeforces 946D
    Invitation Cards POJ-1511 (spfa)
    spfa 单源最短路究极算法
    Currency Exchange POJ
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7144709.html
Copyright © 2011-2022 走看看