「ファイナルJOI 2018は、」毎月のパスを購入します

JOIは、Nステーションがあり、市内に住んでいた1 :: N.番号が付け Mの鉄道、番号の1..Mがあります。ステーションBと鉄道駅のA双方向接続の記事I、旅費C.

IOI JOI高校がステーションTの近傍に位置している間JOIは、駅の近くに住んでS 彼は毎月のパスを購入し、2局からする予定。彼はこのパスを買ったとき、彼は駅と駅S Tパス間の旅費の最小値を選択する必要があります。このパスで、JOIが含まれる任意の選択された経路にレールによって追加のコスト、双方向とすることがありません。

彼はU Vの最小コストようにステーションからステーションへ毎月のパスを購入したいと考えているので、JOIは、多くの場合、駅で駅UとVの近くに本屋に行きます。

彼は駅U Vから駅に行くとき、彼は駅から駅VパスにUを選ぶだろう。パスでこの鉄道パスが範囲を指定した場合、パス上の鉄道の各セグメントに対して、コストは、そうでなければコストC.ゼロであります ステーションからの総コストのステーションVにJOI U鉄道及び各セグメントのコスト。

彼は駅から駅Vの最小コストに毎月のパス、Uを購入した場合である適切なコースを選択し、知りたいと思いました。

あなたは最小限のコストを計算するプログラムを作成する必要があります。

ソリューション:
本当に良い話題ああ
まず、我々は貪欲な戦略が側に最短道路側に最初にすべてのセットのある持っているし、再度最短ランを持っていますが、2つの道路ので、最短の道で二つに困難になる可能性がある問題を持っています
しかし!これは最短の辺はDPの主題に従事しなければならない連続的な経路であることに留意されたいああ最短DAG DAG図はDPは試験条件とDPの主題DPが最短道路に従事したいされているがAであることに留意基づくものではありません最短経路及び条件の最短1 \(DIS [U] == DISは、 [V] +ル[I] \) 我々はDP図DPは、我々ように配列DP上になければならないことができます私は、最短DPの具体的な実装であると考え、トップシーケンスとして利用することができる\(Dijと\)を行います

TOPPシーケンスDAG DP

queue<int> q;
void DP() {
    for (int i = 1; i <= n; fu[i] = vu[i], fv[i] = vv[i], i++)
        if (!deg[i])
            q.push(i);
    while (q.size()) {
        int x = q.front();
        q.pop();
        ans = min(ans, min(fv[x] + vu[x], fu[x] + vv[x]));
        for (int i = las[x]; i; i = pre[i]) {
            int y = to[i];
            fu[y] = min(fu[y], fu[x]), fv[y] = min(fv[y], fv[x]);
            if (--deg[y] == 0)
                q.push(y);
        }
    }
}

コード:

//
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define inf (ll)(1e17)
#define maxnn 2010000
ll las[maxnn],nex[maxnn],le[maxnn],tot,en[maxnn];

ll zlas[maxnn],znex[maxnn],zle[maxnn],ztot,zen[maxnn];
ll flas[maxnn],fnex[maxnn],fle[maxnn],ftot;
ll dis1[maxnn],dis2[maxnn],dis3[maxnn],dis4[maxnn];
ll n,m,s,t,u,v;
struct node
{
    int st,en;
    ll l;
    ll d;
}ed[maxnn];
int cnt;

void add(int a,int b,ll c)
{
    en[++tot]=b;
    nex[tot]=las[a];
    las[a]=tot;
    le[tot]=c;
}

void zadd(int a,int b,ll c)
{
    zen[++ztot]=b;
    znex[ztot]=zlas[a];
    zlas[a]=ztot;
    zle[ztot]=c;
}
typedef pair<ll ,int > P;
priority_queue<P ,vector<P>,greater<P> > Q;
void dij(ll *dis,int v)
{
    for(int i=1;i<=n;i++)
    {
        dis[i]=inf;
    }
    dis[v]=0;
    Q.push(make_pair(dis[v],v));
    while(Q.size())
    {
        P s=Q.top();
        Q.pop();
        if(s.first!=dis[s.second]) continue;
        for(int i=las[s.second];i;i=nex[i])
        {
            int u=en[i];
            if(dis[u]>dis[s.second]+le[i])
            {
                dis[u]=dis[s.second]+le[i];
                Q.push(make_pair(dis[u],u));
            }
        }
    }
}
ll dis[maxnn];
ll f[maxnn][3];
ll ans=111111111000000;
void ddij(int v)
{
    for(int i=1;i<=n;i++)
    {
        f[i][0]=f[i][1]=inf;
    }
    for(int i=1;i<=n;i++)
    {
        dis[i]=inf;
    }
    dis[v]=0;
    f[v][0]=dis3[v];
    f[v][1]=dis4[v];
    Q.push(make_pair(dis[v],v));
    while(Q.size())
    {
        P s=Q.top();
        Q.pop();
        if(s.first!=dis[s.second]) continue;
        for(int i=zlas[s.second];i;i=znex[i])
        {
            int u=zen[i];
            if(dis[u]==dis[s.second]+zle[i])
            {
                dis[u]=dis[s.second]+zle[i];
                f[u][0]=min(f[u][0],min(f[s.second][0],dis3[u]));
                f[u][1]=min(f[u][1],min(f[s.second][1],dis4[u]));
            }
            if(dis[u]>dis[s.second]+zle[i])
            {
                dis[u]=dis[s.second]+zle[i];
                f[u][0]=min(f[s.second][0],dis3[u]);
                f[u][1]=min(f[s.second][1],dis4[u]);
                Q.push(make_pair(dis[u],u));
            }
        }
    }
}
int main()
{
    ll x,y,z;
    scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&s,&t,&u,&v);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
        ed[++cnt].st=x;
        ed[cnt].en=y;
        ed[cnt].l=z;
    }
    dij(dis1,s);
    dij(dis2,t);
    dij(dis3,u);
    dij(dis4,v);
    for(int i=1;i<=cnt;i++)
    {
        if(dis1[ed[i].st]+dis2[ed[i].en]+ed[i].l==dis1[t])
        {
            zadd(ed[i].st,ed[i].en,ed[i].l);
        }
        if(dis1[ed[i].en]+dis2[ed[i].st]+ed[i].l==dis1[t])
        {
            zadd(ed[i].en,ed[i].st,ed[i].l);
        }
    }
    ddij(s);
    for(int i=1;i<=n;i++)
    {
        ans=min(ans,f[i][1]+dis3[i]);
        ans=min(ans,f[i][0]+dis4[i]);
    }
    ans=min(ans,dis3[v]);
    cout<<ans;
    
}

おすすめ

転載: www.cnblogs.com/OIEREDSION/p/11810672.html