XSY2278 HDU5669 [] []レッドサン(セグメントツリー+ダイクストラ)

\(説明\)

所与の(N \)\図ポイントは、標識された点\(1 \)をする(\ N-)\。我々は(M \)\回もの側面を、それぞれの側でもとして説明することができる(\ \) \(B \) \(C \) \(D \) \(W:\)

for i = a to b do

    for j = c to d do

         Add_Edge(i,j,w)        

\(Add_Edge(I、J、 W)\) の点から表す\(iは\)ポイントに\(jは\)とのもコスト(\ W)\双方向エッジ。

ポイント\(1 \)ポイント\(\ N-)最小のコスト。

困難を軽減するために、我々はしている(K \)\あなたは、エッジのコストを排除することができますチャンスを。


\(入力\)

最初の行番号\(T \)は、テスト・データ・セットの数を示している。何らかの理由で、\(T = 1 \)

3つの数の第2行\(N、M、K \)

\(M \)の行を、各行\(5 \)\(A、B、C、 Dは、W \) 、タイトル意味記載されているように。


\(出力\)

最小コストの行番号。

ポイントした場合(1 \)\と点\(N-は\)に接続されていない、出力が「ywwが私たちの赤い太陽です!」 。


\(サンプル入力\)

1
5 3 0
1 2 3 4 5 42
5 5 4 4 468
1 1 3 3 335


\(サンプル出力\)

42


\(ヒント\)

\(^4,1≤M≤10^4,0≤K≤10,1≤w≤10^ 3 \ T =1,1≤N≤5×10)


\(ソース\)

運動セグメントツリーの木4-1-


考え

アイデアを参照することができますCF787D遺産[XSY2434] [] も自分で書かれました)

基本的には同じ考え方

ツリーラインの最適化を使用し、また、ほとんどの短絡問題の一つであります

両者のそれぞれについて\([B] \ ) と\([C、D] \ ) 側部分との間に接続され、我々は、中間点集合\(X \) ([B] \ \を ) \(X \)次いで\(X \)がに接続されている\([C、D] \ )

私たちは今、どのように、ほとんどの短絡のために考慮し始めています

我々は、すべて使用することを知っている\(ダイクストラ\)

しかし、もう一つの制限は、我々がいる\(K \)チャンスあなたは、エッジのコストを排除することができます

だから我々は明らかだと思う\(DP \)

セット\(DIS [I] [jを ] \) 到着表す\(iは\)使用して、ノードを\(J \)最小コストの可能性を

だから我々は、ターンのような方程式を得ることができます:

\(\ [I] \\ DIS [now.x [now.x] [V] = now.cost +ヴァル[I]&DIS [now.x] [V]> now.cost +ヴァルをDIS {ケースを}開始+1] [V] = now.cost&now.x <K且DIS [now.x + 1] [V]> now.cost \端{ケース} \)

私たちは、最短の友達を達成させていただきます


コード

#include<bits/stdc++.h>
using namespace std;
const int N=400010,M=2000010;
int n,m,k,rt1,rt2,cnt=0;
int lc1[N],rc1[N],lc2[N],rc2[N];
int dis[15][N];
bool vis[15][N];
int w;
int to[M<<1],nxt[M<<1],val[M<<1],head[N];
int nodetot=0;
struct edge
{
    int u,cost,x;
    bool operator < (const edge & e)const
    {
        return cost>e.cost;
    }
};
void add(int u,int v,int wi)
{
    to[++cnt]=v;
    val[cnt]=wi;
    nxt[cnt]=head[u];
    head[u]=cnt;
}
int build1(int l,int r)
{
    if(l==r)return l;
    int now=++nodetot;
    int mid=(l+r)>>1;
    lc1[now-n]=build1(l,mid);
    add(lc1[now-n],now,0);
    rc1[now-n]=build1(mid+1,r);
    add(rc1[now-n],now,0);
    return now;
}
int build2(int l,int r)
{
    if(l==r)return l;
    int now=++nodetot;
    int mid=(l+r)>>1;
    lc2[now-n]=build2(l,mid);
    add(now,lc2[now-n],0);
    rc2[now-n]=build2(mid+1,r);
    add(now,rc2[now-n],0);
    return now;
}
void modify1(int k,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr)
    {
        add(k,nodetot,w);
        return ;
    }
    int mid=(l+r)>>1;
    if(ql<=mid)modify1(lc1[k-n],l,mid,ql,qr);
    if(qr>mid)modify1(rc1[k-n],mid+1,r,ql,qr);
}
void modify2(int k,int l,int r,int ql,int qr) 
{
    if(ql<=l&&r<=qr)
    {
        add(nodetot,k,0);
        return ;    
    }
    int mid=(l+r)>>1;
    if(ql<=mid)modify2(lc2[k-n],l,mid,ql,qr);
    if(qr>mid)modify2(rc2[k-n],mid+1,r,ql,qr);
}
priority_queue<edge>qu;
void dijkstra()
{
    memset(dis,127,sizeof(dis));
    dis[0][1]=0;
    qu.push((edge){1,0,0});
    edge now;
    while(!qu.empty())
    {
        now=qu.top();
        qu.pop();
        if(vis[now.x][now.u])continue;
        vis[now.x][now.u]=1;
        for(int i=head[now.u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[now.x][v]>now.cost+val[i]&&!vis[now.x][v])
            {
                dis[now.x][v]=now.cost+val[i];
                qu.push((edge){v,dis[now.x][v],now.x});
            }
            if(now.x<k&&!vis[now.x+1][v]&&dis[now.x+1][v]>now.cost)
            {
                dis[now.x+1][v]=now.cost;
                qu.push((edge){v,dis[now.x+1][v],now.x+1});
            }
        }
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d %d %d",&n,&m,&k);
    int a,b,c,d;
    nodetot=n;
    rt1=build1(1,n);
    rt2=build2(1,n);
    while(m--)
    {   
        scanf("%d %d %d %d %d",&a,&b,&c,&d,&w);
        nodetot++;//中间点
        modify1(rt1,1,n,a,b);modify2(rt2,1,n,c,d);
        nodetot++;//中间点
        modify1(rt1,1,n,c,d);modify2(rt2,1,n,a,b);
    }
    dijkstra();
    int ans=dis[0][0];
    for(int i=0;i<=k;i++)ans=min(ans,dis[i][n]);
    if(ans==dis[0][0])puts("Yww is our red sun!");
    else printf("%d",ans);
    return 0; 
} 

おすすめ

転載: www.cnblogs.com/ShuraEye/p/11622663.html