1. 程式人生 > >【GDOI 2016 Day2】第一題 SigemaGO

【GDOI 2016 Day2】第一題 SigemaGO

一次 img 分析 const using sin log str n+1

題目

技術分享圖片

分析

拆點連邊+spfa。
首先把圖分成2lim+1層,也就是每個點拆成2lim+1個點。
如果a和b之間、b和c有一條有向邊,那麽連邊(k,a)-->(k+1,b),(k+1,b)-->(k+2,c)(k=1、3、5、···、2lim+1,是當前點所在的層數),這兩條邊的權值和是l。也就是說當走了(k,a)-->(k+1,b)-->(k+2,c)這條路線時,就是抄了一次近道。
註意:在spfa中,當走到的點在第2、4、6、···、2lim層時,就只能往上走,因為當前點一定在抄近道的過程中。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
using namespace std;
int next[800000],last[800000],to[800000],dis[13][200000],n,m,lim,l,tot,v[800000],ans,d[10000000][2];
bool bz[200000];
int bj(int x,int y,int z)
{
    next[++tot]=last[x];
    last[x]=tot;
    to[tot]=y;
    v[tot]=z;
}
int spfa()
{
    int i,j,head=0,tail=1,k;
    d[1][0]=0;
    d[1][1]=1;
    dis[0][1]=0;
    while(head<tail)
    {
        k=++head;
        bz[d[k][0]*n+d[k][1]]=true;
        for(i=last[d[k][1]+n*d[k][0]];i;i=next[i])
        {
            j=to[i];
            int x=(j-1)/n;
            if(dis[x][(j-1)%n+1]>dis[d[k][0]][d[k][1]]+v[i])
            {
                dis[x][(j-1)%n+1]=dis[d[k][0]][d[k][1]]+v[i];
                if(bz[j])
                {
                    bz[j]=false;
                    d[++tail][0]=x;
                    d[tail][1]=(j-1)%n+1;
                }
            }
        }
    }
}
int main()
{
    freopen("sigemago.in","r",stdin);
    freopen("sigemago.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&l,&lim);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        for(int j=1;j<=lim+1;j++)
        {
            bj(x+n*(j*2-2),y+n*(j*2-2),z);
        }
        for(int j=1;j<=lim*2;j++)
        {
            bj(x+n*(j-1),y+n*j,l*(j%2));
        }
    }
    memset(dis,60,sizeof(dis));
    memset(bz,true,sizeof(bz));
    spfa();
    ans=maxlongint;
    for(int i=1;i<=lim+1;i++)
    {
        if(ans>dis[i*2-2][n]) ans=dis[i*2-2][n];
    }
    if(ans>=dis[0][0])  printf("-1\n");
    else
    printf("%d\n",ans);
}

【GDOI 2016 Day2】第一題 SigemaGO