zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    修复PLSQL Developer 与 Office 2010的集成导出Excel 功能
    Using svn in CLI with Batch
    mysql 备份数据库 mysqldump
    Red Hat 5.8 CentOS 6.5 共用 输入法
    HP 4411s Install Red Hat Enterprise Linux 5.8) Wireless Driver
    变更RHEL(Red Hat Enterprise Linux 5.8)更新源使之自动更新
    RedHat 5.6 问题简记
    Weblogic 9.2和10.3 改密码 一站完成
    ExtJS Tab里放Grid高度自适应问题,官方Perfect方案。
    文件和目录之utime函数
  • 原文地址:https://www.cnblogs.com/lokiii/p/9371532.html
Copyright © 2011-2022 走看看