zoukankan      html  css  js  c++  java
  • [Usaco2009 Feb]Revamping Trails 道路升级

    题目描述

    每天,农夫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的时间尽量少.

    输入格式

    第一行: 三个空格分开的数: N, M, 和 K

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

    输出格式

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


    解法1:

    动态规划。设dis(i,j)表示更新了j条路径之后i的最短路,设pre(u)表示u的前驱节点,那么:

    [dis[i][j]=Min_{k{in}pre(i)}{{}Min(dis[k][j]+edge(k,i),dis[k][j-1]){}} ]

    解法2:

    分层图最短路,把原图多建k层,若原图中存在edge(u,v),那么把每层的u都往下一层的v连一条长度为0的有向边,然后跑最短路即可。答案为每一层终点的最短路的最小值

    时间复杂度都是O((N+M)log(K*(N+M)))。给出分层图最短路的代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define maxn 10001
    #define maxm 50001
    #define maxk 21
    using namespace std;
     
    struct edge{
        int to,dis,next;
        edge(){}
        edge(const int &_to,const int &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }
    }e[maxm*maxk*4];
    int head[maxn*maxk],k;
     
    int dis[maxn*maxk];
    bool vis[maxn*maxk];
    int n,m,q,s,t;
     
    inline int read(){
        register int x(0),f(1); register char c(getchar());
        while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
        while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    inline void add(const int &u,const int &v,const int &w){ e[k]=edge(v,w,head[u]),head[u]=k++; }
     
    inline void dijkstra(){
        priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > > q;
        memset(dis,0x3f,sizeof dis),dis[1]=0;
        q.push(make_pair(0,1));
        while(q.size()){
            int u=q.top().second; q.pop();
            if(vis[u]) continue; vis[u]=true;
            for(register int i=head[u];~i;i=e[i].next){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].dis) dis[v]=dis[u]+e[i].dis,q.push(make_pair(dis[v],v));
            }
        }
    }
     
    int main(){
        memset(head,-1,sizeof head);
        n=read(),m=read(),q=read();
        for(register int i=1;i<=m;i++){
            int u=read(),v=read(),w=read();
            for(register int j=0;j<=q;j++) add(u+n*j,v+n*j,w),add(v+n*j,u+n*j,w);
            for(register int j=1;j<=q;j++) add(u+n*(j-1),v+n*j,0),add(v+n*(j-1),u+n*j,0);
        }
        dijkstra();
     
        int ans=0x3f3f3f3f;
        for(register int i=0;i<=q;i++) ans=min(ans,dis[n+n*i]);
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Microsoft .NET Framework 以及 CLR 的版本
    如何:备份 Team Foundation Server
    通过VS2008SP1 访问TFS2010
    Project 2007 Understanding Project's Percent Complete vs. Percent Work Complete
    TFS:从单服务器部署移到双服务器部署
    C#网络编程(基本概念和操作) Part.1
    图解Windows server 2012故障转移群集的安装、建立
    产品经理经验总结
    TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍
    Windows Phone开发概论
  • 原文地址:https://www.cnblogs.com/akura/p/10975936.html
Copyright © 2011-2022 走看看