• [USACO11JAN] Roads and Planes G


    题目

    (Farmer John)正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到(T)个城镇((1 <= T <= 25,000)),编号为(1)(T)。这些城镇之间通过(R)条道路((1 <= R <= 50,000),编号为(1)(R)) 和(P)条航线 ((1 <= P <= 50,000),编号为(1)(P)) 连接。每条道路(i)或者航线(i)连接城镇(A_i)((1 <= A_i <= T))到(B_i)((1 <= B_i <= T)),花费为(C_i)。对于道路,(0 <= C_i <= 10,000);然而航线的花费很神奇,花费(C_i)可能是负数((-10,000 <= C_i <= 10,000))。道路是双向的,可以从(A_i)(B_i),也可以从(B_i)(A_i),花费都是(C_i)。然而航线与之不同,只可以从(A_i)(B_i)。事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策保证:如果有一条航线可以从(A_i)(B_i),那么保证不可能通过一些道路和航线从(B_i)回到(A_i)。由于(FJ)的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇(S(1 <= S <= T))把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。

    Input

    • (1)行:四个空格隔开的整数:$ T, R, P,$and (S)

    • (2)(R+1)行:三个空格隔开的整数(表示一条道路):(A_i, B_i)(C_i)

    • (R+2)(R+P+1)行:三个空格隔开的整数(表示一条航线):(A_i, B_i)(C_i)

    Output

    • (1)(T)行:从(S)到达城镇(i)的最小花费,如果不存在输出"NO PATH"。

    Sample Input

    6 3 3 4

    1 2 5

    3 4 5

    5 6 10

    3 5 -100

    4 6 -100

    1 3 -10

    样例输入解释:

    一共六个城镇。在(1-2,3-4,5-6)之间有道路,花费分别是(5,5,10)。同时有三条航线:(3->5,4->6)(1->3),花费分别是(-100,-100,-10)(FJ)的中心城镇在城镇(4)

    Sample Output

    NO PATH

    NO PATH

    5

    0

    -95

    -100

    样例输出解释:

    (FJ)的奶牛从(4)号城镇开始,可以通过道路到达(3)号城镇。然后他们会通过航线达到(5)(6)号城镇。

    但是不可能到达(1)(2)号城镇。

    解说

    幻影忍者前情提要: 这是一个勇敢的少年永不言弃地和时间抗争终于取得了胜利的故事。

    首先看一眼题,这不就是很裸的最短路吗?有负边直接跑一遍(SPFA)就完了啊!而且题目保证了没有负环连判断都不用!

    之后……(Vjudge)(T)掉了,洛谷(T)两个点……

    [托腮][托腮]

    有什么办法可以优化时间效率呢?

    经过一番查找,我发现了一种叫做双向对列的优化方法。就是说,在把点入队的时候把目前的距离和队首元素比较一下,如果比队首元素大就推到队尾,否则放在队首,这样的话就可以尽量减少之后的点入队的次数从而达到优化效果。

    现在结果如何?(Vjudge)成功卡过了,洛谷还是(T)了一个点。

    [托腮][托腮]

    再经过我一番查找,我又发现了一种叫做(inline)的东西,加在函数之前好像会快一点。讲解我看了半天没看懂……所以直接用了,然后就(A)了(我无话可说了)。

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<string>
    #include<queue>
    using namespace std;
    const int maxn=25000+3,maxe=150000+3,inf=1000000000;
    int t,r,p,s,tot,head[maxn],dis[maxn],to[maxe],w[maxe],next[maxe];
    bool vis[maxn];
    deque<int> q;
    void add(int a,int b,int l){
    	w[++tot]=l;
    	to[tot]=b;
    	next[tot]=head[a];
    	head[a]=tot;
    }
    inline void Spfa(int begin){
    	for(int i=1;i<=t;i++) dis[i]=inf;
    	dis[begin]=0,vis[begin]=1;
    	q.push_back(begin);
    	while(!q.empty()){
    		int u=q.front();
    		q.pop_front();
    		vis[u]=0;
    		for(int i=head[u];i;i=next[i]){
    			int v=to[i];
    			if(dis[v]>dis[u]+w[i]){
    				dis[v]=dis[u]+w[i];
    				if(!vis[v]){
    					if(!q.empty()&&dis[v]>=dis[q.front()]) q.push_back(v);
                        else q.push_front(v);
    					vis[v]=1;
    				}
    			}
    		}
    	}
    }
    
    int main(){
    	tot=1;
    	scanf("%d%d%d%d",&t,&r,&p,&s); 
    	int x,y,w;
    	for(int i=1;i<=r;i++){	
    		scanf("%d%d%d",&x,&y,&w);
    		add(x,y,w);
    		add(y,x,w);
    	}
    	for(int i=1;i<=p;i++){	
    		scanf("%d%d%d",&x,&y,&w);
    		add(x,y,w);
    	}
    	Spfa(s);
    	for(int i=1;i<=t;i++){
    		if(dis[i]==inf) printf("NO PATH
    ");
    		else printf("%d
    ",dis[i]);
    	}
    	return 0;
    }
    

    幸甚至哉,歌以咏志。

  • 相关阅读:
    python2和3切换时的几个注意点会报错
    Python异常UnicodeEncodeError 'gbk' codec can't encode character 'xa0'
    python爬虫使用Xpath爬取指定位置的内容
    问题账户需求分析
    2018年春季个人阅读计划
    我们应当怎样做需求分析
    人月神话读后感3
    人月神话读后感2
    线程池
    生产者消费者
  • 原文地址:https://www.cnblogs.com/DarthVictor/p/12804169.html
Copyright © 2020-2023  润新知