USACO 2009 Feb Gold 3.Revamping Trails

题目描述

Description

每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N; 1 <= P2_i<= N). John需要T_i (1 <= T_i <= 1,000,000)时间单位用道路i从P1_i走到P2_i或者从P2_i 走到P1_i 他想更新一些路经来减少每天花在路上的时间.具体地说,他想更新K (1 <= K <= 20)条路经,将它们所须时间减为0.帮助FJ选择哪些路经需要更新使得从1到N的时间尽量少.

Input

第一行: 三个空格分开的数: N, M, 和 K * 第2..M+1行: 第i+1行有三个空格分开的数:P1_i, P2_i, 和 T_i

Output

第一行: 更新最多K条路经后的最短路长度.

题目分析

分层图最短路 f[i][j]表示改变j条路径后 从1~i的最短距离

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
int n,m,k;
int start,end;
int head[200000];
int next[200000];
int to[200000];
int val[200000];
bool vis[20000][22];
int f[20000][22];
struct your
{
    int x,t;
};
int read()
{
    int sum=0;
    char c;
    c=getchar();
    while(c==' '||c=='\n')
        c=getchar();
    while(c<='9'&&c>='0')
        sum=(sum<<3)+(sum<<1)+(c-'0'),c=getchar();
    return sum;
}
struct cmp
{
    bool operator()(const your j,const your k)
    {
        return f[j.x][j.t]>f[k.x][k.t];
    } 
};
priority_queue<your,vector<your>,cmp>q;
void spfa()
{
    your nmp;
    nmp.x=1;
    nmp.t=0;
    memset(f,0x3f,sizeof f);
    f[1][0]=0;
    vis[1][0]=1;
    q.push(nmp);
    while(q.size())
    {
        nmp=q.top();
        q.pop();
        vis[nmp.x][nmp.t]=false;
        for(int i=head[nmp.x];i;i=next[i])
        {
            if(f[to[i]][nmp.t]>f[nmp.x][nmp.t]+val[i])
            {
                f[to[i]][nmp.t]=f[nmp.x][nmp.t]+val[i];
                if(!vis[to[i]][nmp.t])
                {
                    your tmp;
                    tmp.x=to[i];
                    tmp.t=nmp.t;
                    vis[to[i]][nmp.t]=true;
                    q.push(tmp);
                }
            }
        }
        if(nmp.t==k) continue;
        for(int i=head[nmp.x];i;i=next[i])
        {
            if(f[to[i]][nmp.t+1]>f[nmp.x][nmp.t])
            {
                f[to[i]][nmp.t+1]=f[nmp.x][nmp.t];
                if(!vis[to[i]][nmp.t+1])
                {
                    your tmp;
                    tmp.x=to[i];
                    tmp.t=nmp.t+1;
                    vis[to[i]][nmp.t+1]=true;
                    q.push(tmp);
                }
            }
        }
    }
}
int tot;
void add(int x,int y,int c)
{
    next[++tot]=head[x];
    to[tot]=y;
    val[tot]=c;
    head[x]=tot;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++)
    {
        int x,y,c;
        x=read();
        y=read();
        c=read();
        add(x,y,c);
        add(y,x,c);
    }
    spfa();
    int ans=0x7f7f7f7f;
    for(int i=0;i<=k;i++)
        ans=min(ans,f[n][i]);
    printf("%d",ans);
    return 0;
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注