zoukankan      html  css  js  c++  java
  • [Usaco2007 Feb]Cow Party

    题目描述

    农场有N(1≤N≤1000)个牛棚,每个牛棚都有1只奶牛要参加在X牛棚举行的奶牛派对.共有M(1≤M≤100000)条单向路连接着牛棚,第i条踣需要Ti的时间来通过.牛们都很懒,所以不管是前去X牛棚参加派对还是返回住所,她们都采用了用时最少的路线.那么,用时最多的奶牛需要多少时间来回呢?

    输入格式

    第1行:三个用空格隔开的整数.

    第2行到第M+1行,每行三个用空格隔开的整数:Ai, Bi,以及Ti.表示一条道路的起点,终点和需要花费的时间.

    输出格式

    唯一一行:一个整数: 所有参加聚会的奶牛中,需要花费总时间的最大值.


    回去的最少时间好算,就是单源多汇最短路,dijkstra跑一遍就可以了。但是过来的最少时间呢?

    问题变成了多源最短路。但不要急着敲Floyd,可以注意到虽然是多源,但是是单汇。如果是从汇点往源点跑的话就可以用dijkstra了。所以在原图的基础上建个反图,过来的时候跑反图,回去的时候跑正图,时间复杂度为O((N+M)*N),加堆优化就是O((N+M)logN)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define maxn 1001
    #define maxm 100001
    using namespace std;
     
    struct graph{
        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];
        int head[maxn],k;
        inline void init(){ memset(head,-1,sizeof head); }
        inline void add(const int &u,const int &v,const int &w){
            e[k]=edge(v,w,head[u]),head[u]=k++;
        }
    }a,b;
     
    int dis[maxn],ans[maxn];
    bool vis[maxn];
    int n,m,s;
    priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > > q;
     
    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 dijkstra(const graph &g){
        memset(dis,0x3f,sizeof dis),memset(vis,false,sizeof vis);
        q.push(make_pair(0,s)),dis[s]=0;
        while(q.size()){
            int u=q.top().second; q.pop();
            if(vis[u]) continue; vis[u]=true;
            for(register int i=g.head[u];~i;i=g.e[i].next){
                int v=g.e[i].to;
                if(dis[v]>dis[u]+g.e[i].dis){
                    dis[v]=dis[u]+g.e[i].dis;
                    q.push(make_pair(dis[v],v));
                }
            }
        }
    }
     
    int main(){
        a.init(),b.init();
        n=read(),m=read(),s=read();
        for(register int i=1;i<=m;i++){
            int u=read(),v=read(),w=read();
            a.add(u,v,w),b.add(v,u,w);
        }
        dijkstra(a);
        for(register int i=1;i<=n;i++) ans[i]+=dis[i];
        dijkstra(b);
        for(register int i=1;i<=n;i++) ans[i]+=dis[i];
     
        int mmax=0;
        for(register int i=1;i<=n;i++) mmax=max(mmax,ans[i]);
        printf("%d
    ",mmax);
        return 0;
    }
    
  • 相关阅读:
    作为计算机专业的过来人:想学好C 语言,你必须要知道这3个原因(强烈推荐)
    C语言从1972年诞生至今,能够恒久不衰,是怎么做到的?
    这4种胜过C语言的 C++ 强制转换方法,真的好用到爆...(建议收藏)
    一纸学历证书真的胜过多年工作经验吗?HR更看重程序员什么地方?
    《个人-GIT使用方法》
    java Comparable 和 Cloneable接口
    Java 文本I/O 处理
    java 异常处理
    java的一维数组
    java中String类型
  • 原文地址:https://www.cnblogs.com/akura/p/10864641.html
Copyright © 2011-2022 走看看