1. 程式人生 > >分層圖【p2939】[USACO09FEB]改造路Revamping Trails

分層圖【p2939】[USACO09FEB]改造路Revamping Trails

Description

約翰一共有N)個牧場.由M條佈滿塵埃的小徑連線.小徑可 以雙向通行.每天早上約翰從牧場1出發到牧場N去給奶牛檢查身體.

通過每條小徑都需要消耗一定的時間.約翰打算升級其中K條小徑,使之成為高 速公路.在高速公路上的通行幾乎是瞬間完成的,所以高速公路的通行時間為0.

請幫助約翰決定對哪些小徑進行升級,使他每天從1號牧場到第N號牧場所花的時間最短

分層圖最短路的裸題..

就不多BB了.

程式碼

#include<cstdio>
#include<queue>
#include<cstring>
#define R register
#define N 20008
using namespace std;
inline void in(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s>'9' or s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s>='0' and s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int head[N],tot,n,m,s,t,k;
int dis[N][25],ans=2147483647;
bool vis[N][25];
struct cod{int u,v,w;}edge[N*6+8];
inline void add(int x,int y,int z)
{
    edge[++tot].u=head[x];
    edge[tot].v=y;
    edge[tot].w=z;
    head[x]=tot;
}
struct coc{
    int u,d,used;
    bool operator <(const coc&a) const 
    {
        return d>a.d;
    }
};
inline void dijkstra()
{
    memset(dis,127,sizeof dis);
    dis[s][0]=0;
    priority_queue<coc>q;
    q.push((coc){s,0,0});
    while(!q.empty())
    {
        int u=q.top().u,now=q.top().used;
        q.pop();
        if(vis[u][now])continue;
        vis[u][now]=true;
        for(R int i=head[u];i;i=edge[i].u)
        {
            if(now<k and !vis[edge[i].v][now+1] and dis[edge[i].v][now+1]>dis[u][now])
            {
                dis[edge[i].v][now+1]=dis[u][now];
                q.push((coc){edge[i].v,dis[edge[i].v][now+1],now+1});
            }
            if(!vis[edge[i].v][now] and dis[edge[i].v][now]>dis[u][now]+edge[i].w)
            {
                dis[edge[i].v][now]=dis[u][now]+edge[i].w;
                q.push((coc){edge[i].v,dis[edge[i].v][now],now});
            }
        }
    }
}
int main()
{
    in(n),in(m),in(k);s=1;t=n;
    for(R int i=1,x,y,z;i<=m;i++)
    {
        in(x),in(y),in(z);
        add(x,y,z);add(y,x,z);
    }
    dijkstra();
    for(R int i=0;i<=k;i++)
        ans=min(ans,dis[t][i]);
    printf("%d",ans);
}