bzoj 1579: [Usaco2009 Feb] Revamping Trails Road Upgrade [Layered Map+spfa]

I don't need dijskstra series 2333 until I die. Luogu has a point on T and opened O2. The
basic idea is to build a layered graph, that is, to build a k+1 layer of the original image, and then place the edge of the original image between the two adjacent layers. The starting point of the previous layer is connected to the end point of the next layer, and the edge weight is 0, which means that the edge weight of this edge is exempted, and then the answer is the shortest path from s in the 0th layer to t in the k layer, because the 0-weight edge It is always connected from the previous layer to the next layer, so reaching the k layer means that k 0-weight edges
have been taken. The number of points is nk. No matter it is dijskstra or spfa, it can't run
. Then carefully observe the characteristics of this picture and find that For the update between different layers, only the previous layer updates the next layer through the 0-weight edge, so consider a single-layer update, each layer does a spfa, and then use the shortest path and 0 weight that the previous layer ran through when crossing layers. Update the next layer
and then add an SLF optimization to spfa.

#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])
            {
                d[e[i].to]=dis[e[i].no];
                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\n",dis[n]);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325203336&siteId=291194637