Dijkstra,最短路树(战争和物流,LA 4080)

来源:互联网 发布:一比一可拆卸枪模淘宝 编辑:程序博客网 时间:2024/04/29 02:13

学会了最短路树。


pdf链接:https://icpcarchive.ecs.baylor.edu/external/40/4080.pdf


#include<bits/stdc++.h>#include<limits.h>using namespace std;typedef long long ll;const ll maxn = 110;const ll maxm = 1010;const ll inf = LONG_LONG_MAX>>2;struct Edge{    ll from,to,dist;};struct HeapNode{    ll d,u;    bool operator < (const HeapNode& rhs) const    {        return d>rhs.d;    }};struct Dijkstra{    ll n,m;    ll xxx;    vector<Edge>edges;    vector<ll>G[maxn];    ll done[maxn];    ll d[maxn];    ll p[maxn];    void init(ll n)    {        xxx=-2;        this->n=n;        edges.clear();        for(ll i=0;i<n;i++)        {            G[i].clear();            done[i]=0;            d[i]=inf;        }    }    void init2(ll n)    {        for(ll i=0;i<n;i++)        {            done[i]=0;            d[i]=inf;        }    }    void add(ll u,ll v,ll dist)    {        edges.push_back((Edge){u,v,dist});        edges.push_back((Edge){v,u,dist});        m=edges.size();        G[u].push_back(m-2);        G[v].push_back(m-1);    }    void dijkstra(ll s)    {        priority_queue<HeapNode>Q;        Q.push((HeapNode){0,s});        d[s]=0;        while(!Q.empty())        {            HeapNode x=Q.top();Q.pop();            ll u=x.u;            if(done[u]) continue;            done[u]=1;            for(unsigned int i=0;i<G[u].size();i++)            {                if(G[u][i]==xxx||G[u][i]==xxx+1) continue;                Edge& e=edges[G[u][i]];                if(d[e.to]>d[e.from]+e.dist)                {                    d[e.to]=d[e.from]+e.dist;                    p[e.to]=G[u][i];                    Q.push((HeapNode){d[e.to],e.to});                }            }        }    }};ll N,M,L,U[maxm],V[maxm],W[maxm];Dijkstra DIJ[maxn][2];ll id[maxn];ll GetAns(){    ll ret=0;    for(ll i=0;i<N;i++)        for(ll j=0;j<N;j++)        {            Dijkstra& D=DIJ[i][id[i]];            if(D.d[j]==inf) ret+=L;            else ret+=D.d[j];        }    return ret;}int main(){    while(scanf("%lld %lld %lld",&N,&M,&L)==3)    {        ll ans=0;        for(ll i=0;i<N;i++)        {            DIJ[i][0].init(N);            DIJ[i][1].init(N);        }        for(ll i=0;i<M;i++)        {            scanf("%lld %lld %lld",&U[i],&V[i],&W[i]);            U[i]--;            V[i]--;            for(ll j=0;j<N;j++)            {                DIJ[j][0].add(U[i],V[i],W[i]);                DIJ[j][1].add(U[i],V[i],W[i]);            }        }        for(ll i=0;i<N;i++) DIJ[i][0].dijkstra(i);        memset(id,0,sizeof(id));        printf("%lld ",GetAns());        for(ll i=0;i<M;i++)        {            memset(id,0,sizeof(id));            for(ll j=0;j<N;j++)            {                if(DIJ[j][0].d[U[i]]==DIJ[j][0].d[V[i]]+W[i]||DIJ[j][0].d[V[i]]==DIJ[j][0].d[U[i]]+W[i])                {                    id[j]=1;                    DIJ[j][1].xxx=i<<1;                    DIJ[j][1].init2(N);                    DIJ[j][1].dijkstra(j);                }            }            ans=max(ans,GetAns());        }        printf("%lld\n",ans);    }    return 0;}


0 0