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;
    }
    


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

  • 相关阅读:
    洛谷 P2108 学英语
    洛谷 P1010 幂次方
    洛谷 P1101 单词方阵
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes
    洛谷 P1553 数字反转(升级版)
    hdu_1348_Wall(凸包)
    hdu_1392_Surround the Trees(凸包)
    hdu_1115_Lifting the Stone(求多边形重心)
    Codeforces Round #354 (Div. 2)_Vasya and String(尺取法)
    hdu_1558_Segment set(并查集+计算几何)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4827999.html
Copyright © 2011-2022 走看看