zoukankan      html  css  js  c++  java
  • la4080 Warfare And Logistics 罗列+最短

          为了图。计算最短随机分ans1。和删除边缘。免费才能够获得最大和短路之间的最大分ans2,如果这两个不沟通。看作是两个点之间的最短距离l。

    第一个想法是枚举每个边缘,然后运行n最短时间。但是,这种复杂性是1000*1000*100*log(100),太大了..事实上在固定起点,求出单元最短路的时候。同一时候能够求出单源最短路树,仅仅有删除的边在树上的时候。源点到任一点的最短路才会有变化,所以在每次跑单源最短路的时候,仅仅须要枚举树上的n-1条边就能够了。累加一下删除每一条边时,在当前源点的情况下。最短距离之和的添加量,最后枚举找一条添加量最大的边就能够了。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <cstring>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const ll inf=(1LL<<61);
    ll cost[2020];
    int n,m;
    ll l;
    
    struct HeapNode
    {
    
        ll d;
        int u;
        bool operator< (const HeapNode& rhs) const
        {
            return d>rhs.d;
        }
        HeapNode(){}
        HeapNode(ll x,int y)
        {
            d=x;
            u=y;
        }
    };
    struct Edge
    {
        int u,v;
        ll w;
        bool ok;
        Edge(){}
        Edge(int x,int y,ll z)
        {
            u=x;
            v=y;
            w=z;
            ok=true;
        }
    };
    const int maxn=105;
    struct Dij
    {
        int n,m;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool done[maxn];
        ll d[maxn];
        int p[maxn];
        void init(int n)
        {
            this->n=n;
    
            for (int i=0; i<=n; i++)
            {
                G[i].clear();
            }
            edges.clear();
        }
        void addedge(int x,int y,ll z)
        {
            edges.push_back((Edge(x,y,z)));
            m=edges.size();
            G[x].push_back(m-1);
        }
        void dijkstra(int s)
        {
            priority_queue<HeapNode> q;
            for (int i=0; i<=n; i++)
            d[i]=inf;
            d[s]=0;
            memset(done,0,sizeof done);
            memset(p,-1,sizeof p);
            q.push(HeapNode(0,s));
            while(!q.empty())
            {
                HeapNode x=q.top(); q.pop();
                int u=x.u;
                if (done[u]) continue;
                done[u]=true;
                for (int i=0; i<G[u].size(); i++)
                {
                    Edge &e=edges[G[u][i]];
                    if (!e.ok) continue;
    
                    if (d[e.v]>d[u]+e.w)
                    {
                        d[e.v]=d[u]+e.w;
                        p[e.v]=G[u][i];
                        q.push(HeapNode(d[e.v],e.v));
                    }
                }
            }
        }
        int tp[maxn];
        ll slove(int s)
        {
            ll res=0;
            ll add=0;
            ll tmp=0;
            ll maxx=0;
            for (int i=1; i<=n; i++)
            {
                if (d[i]<inf)res+=d[i];
                else res+=l;
            }
            memcpy(tp,p,sizeof p);
            for (int i=1;i<=n; i++)
            {
                if (tp[i]!=-1)
                {
                    edges[tp[i]].ok=false;
                    edges[tp[i]^1].ok=false;
                    dijkstra(s);
                    tmp=0;
                    for (int j=1; j<=n; j++)
                    {
                      if (d[j]<inf) tmp+=d[j];
                      else tmp+=l;
                    }
                    cost[tp[i]]+=(tmp-res);
                    cost[tp[i]^1]+=(tmp-res);
                    edges[tp[i]].ok=true;
                    edges[tp[i]^1].ok=true;
                }
            }
            return res;
        }
    }work;
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        while (~scanf("%d%d%lld",&n,&m,&l))
        {
            int x,y;
            ll z;
            work.init(n);
            for (int i=1; i<=m; i++)
            {
                scanf("%d%d%lld",&x,&y,&z);
                work.addedge(x,y,z);
                work.addedge(y,x,z);
            }
            memset(cost,0,sizeof cost);
            ll ans=0;
            for (int i=1; i<=n; i++)
            {
                work.dijkstra(i);
                ans+=work.slove(i);
            }
            int id=0;
            ll maxx=0;
            ll ans2=0;
            for (int i=0; i<work.edges.size(); i++)
            {
                if (cost[i]>maxx)
                {
                    id=i;
                    maxx=cost[i];
                }
            }
            work.edges[id].ok=false;
            work.edges[id^1].ok=false;
            for (int i=1; i<=n; i++)
            {
                work.dijkstra(i);
                for (int j=1; j<=n; j++)
                if (work.d[j]<inf) ans2+=work.d[j];
                else ans2+=l;
            }
            cout<<ans<<" "<<ans2<<endl;
    
        }
        return 0;
    }
    


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    Siege 3.0 正式版发布,压力测试工具
    Pomm 1.1.2 发布,专为 PG 设计的 ORM 框架
    Whonix 0.5.6 发布,匿名通用操作系统
    国内开源 java cms,Jspxcms 2.0 发布
    EZNamespaceExtensions.Net v2013增加对上下文菜单、缩略图、图标、属性表的支持
    GNU Guile 2.0.9 发布,Scheme 实现
    jdao 1.0.4 发布 轻量级的orm工具包
    OpenSearchServer 1.4 RC4 发布
    Percona Server for MySQL 5.5.3030.2
    Samba 4.0.5 发布
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4827999.html
Copyright © 2011-2022 走看看