• bzoj 2662: [BeiJing wc2012]冻结【分层图+spfa】


    死活想不到分层图emmm
    基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为val/2,表示免了这条边的边权,然后答案就是第0层的s到k层的t的最短路,因为0权边总是从上一层连到下一层,所以到达k层就表示走了k条0权边
    然后仔细观察这张图的特性,发现不同层之间的更新只有上一层通过val/2权边更新下一层,所以考虑单层更新,每一层都做一次spfa,然后跨层的时候用上一层跑过的最短路和0权边更新下一层
    然后再给spfa加一个SLF优化即可

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<ctime>
    using namespace std;
    const int N=50005,inf=1e9;
    int n,m,k,h[N],cnt,dis[N],d[N];
    bool v[N];
    deque<int>q;
    struct qwe
    {
        int ne,no,to,va;
    }e[N<<2];
    int read()
    {
        int r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    inline void add(int u,int v,int w)
    {
        cnt++;
        e[cnt].ne=h[u];
        e[cnt].no=u;
        e[cnt].to=v;
        e[cnt].va=w;
        h[u]=cnt;
    }
    void spfa()
    {
        while(!q.empty())
        {
            int u=q.front();
            q.pop_front();
            v[u]=0;
            for(int i=h[u];i;i=e[i].ne)
                if(dis[e[i].to]>dis[u]+e[i].va)
                {
                    dis[e[i].to]=dis[u]+e[i].va;
                    if(!v[e[i].to])
                    {
                        v[e[i].to]=1;
                        if(!q.empty()&&dis[q.front()]>dis[e[i].to])
                            q.push_front(e[i].to);
                        else
                            q.push_back(e[i].to);
                    }
                }
        }
    }
    int main()
    {
        n=read(),m=read(),k=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),z=read();
            add(x,y,z),add(y,x,z);
            // for(int j=0;j<=k;j++)
                // add(x+j*n,y+j*n,z),add(y+j*n,x+j*n,z);
            // for(int j=1;j<=k;j++)
                // add(x+(j-1)*n,y+j*n,0),add(y+(j-1)*n,x+j*n,0);
        }
        for(int i=1;i<=n;i++)
            dis[i]=inf;
        // clock_t st,ed;
        // st=clock();
        v[1]=1,dis[1]=0,q.push_back(1);
        spfa();
        for(int con=1;con<=k;con++)
        {
            for(int i=1;i<=n;i++)
                d[i]=inf;
            v[1]=1,dis[1]=0,q.push_back(1);
            for(int i=1;i<=cnt;i++)
                if(d[e[i].to]>dis[e[i].no]+e[i].va/2)
                {
                    d[e[i].to]=dis[e[i].no]+e[i].va/2;
                    if(!v[e[i].to])
                    {
                        v[e[i].to]=1;
                        if(!q.empty()&&d[q.front()]>d[e[i].to])
                            q.push_front(e[i].to);
                        else
                            q.push_back(e[i].to);
                    }
                }
            for(int i=1;i<=n;i++)
                dis[i]=d[i];
            spfa();
        }
        // ed=clock();
        // cerr<<st<<" "<<ed<<" "<<ed-st<<endl;
        printf("%d
    ",dis[n]);
        return 0;
    }
    
  • 相关阅读:
    Javascript-DOM
    我的小站成长之路
    Reverse Proxy Vs Forward Proxy
    SSO-单点统一登录系统的设计与实现
    关于网络实名制
    LoggerOne
    AmpOne
    Get a handle on PHP Handlers
    Which PHP mode? Apache vs CGI vs FastCGI
    强制浏览器在点击回退按钮时重载刷新页面
  • 原文地址:https://www.cnblogs.com/lokiii/p/9371532.html
Copyright © 2020-2023  润新知