一本通 3.2 练习 7」道路和航线

又水又坑的一题,

spfa裸题,但要加deque优化,用堆都不行。。

题目描述

原题来自:USACO 2011 Jan. Gold

Farmer John 正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到 TTT 个城镇 ,编号为 111 到 TTT。这些城镇之间通过 RRR 条道路(编号为 111 到 RRR)和 PPP 条航线(编号为 111 到 PPP)连接。每条道路 iii 或者航线 iii 连接城镇 AiA_iAiBiB_iBi,花费为 CiC_iCi

对于道路,0≤Ci≤1040 \le C_i \le 10^40Ci104,然而航线的花费很神奇,花费 CiC_iCi 可能是负数。道路是双向的,可以从 AiA_iAiBiB_iBi,也可以从 BiB_iBiAiA_iAi,花费都是 CiC_iCi。然而航线与之不同,只可以从 AiA_iAiBiB_iBi

事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策保证:如果有一条航线可以从 AiA_iAiBiB_iBi,那么保证不可能通过一些道路和航线从 BiB_iBi 回到 AiA_iAi。由于 FJ 的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇 SSS 把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。

输入格式

第一行为四个空格隔开的整数:T,R,P,ST, R, P,ST,R,P,S;

第二到第 R+1R+1R+1 行:三个空格隔开的整数(表示一条道路):Ai,BiA_i, B_iAi,BiCiC_iCi

R+2R+2R+2 到 R+P+1R+P+1R+P+1 行:三个空格隔开的整数(表示一条航线):Ai,BiA_i, B_iAi,BiCiC_iCi

输出格式

输出 TTT 行,第 iii 行表示到达城镇 iii 的最小花费,如果不存在输出 NO PATH

样例

样例输入

6 3 3 4 
1 2 5 
3 4 5 
5 6 10 
3 5 -100 
4 6 -100 
1 3 -10

样例输出

NO PATH 
NO PATH 
5 
0 
-95 
-100

样例说明

一共六个城镇。在 111 和 222,333 和 444,555 和 666 之间有道路,花费分别是 5,5,105,5,105,5,10。同时有三条航线:3→53\to 535,4→64\to 646 和 1→31\to 313,花费分别是 −100,−100,−10-100,-100,-10100,100,10。FJ 的中心城镇在城镇 444。FJ 的奶牛从 444 号城镇开始,可以通过道路到达 333 号城镇。然后他们会通过航线达到 555 和 666 号城镇。但是不可能到达 111 和 222 号城镇。

数据范围与提示

对于全部数据,1≤T≤2.5×104,1≤R,P≤5×104,1≤Ai,Bi,S≤T1\le T\le 2.5\times 10^4,1\le R,P\le 5\times 10^4,1\le A_i,B_i,S\le T1T2.5×104,1R,P5×104,1Ai,Bi,ST。保证对于所有道路,0≤Ci≤1040 \le C_i \le 10^40Ci104,对于所有航线,−104≤Ci≤104-10^4 \le C_i \le 10^4104Ci≤104。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxm = 1e5;
 4 const int maxn = 5e4;
 5 
 6 struct edge{
 7     int v,nex,w;
 8 }e[maxm<<1];
 9 
10 int head[maxn],n,m1,m2,s,dis[maxn],vis[maxn],size;
11 
12 void adde(int u,int v,int w){
13     e[size].v=v;e[size].w=w;e[size].nex=head[u];head[u]=size++;
14 }
15 
16 void spfa(){
17     deque<int> q;q.push_back(s);dis[s]=0;
18     while(!q.empty()){
19         int u=q.front();q.pop_front();vis[u]=0;
20         for(int i=head[u];~i;i=e[i].nex){
21             int v=e[i].v;
22             if(dis[v]>dis[u]+e[i].w) {
23                 dis[v]=dis[u]+e[i].w;
24                 if(!vis[v]){
25                     if(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);
26                     else q.push_back(v);vis[v]=1;
27                 }
28             }
29         }
30     }
31 }
32 
33 int main(){
34     scanf("%d%d%d%d",&n,&m1,&m2,&s);
35     memset(head,-1,sizeof(head));
36     for(int i=1;i<=m1;i++){
37         int u,v,w;scanf("%d%d%d",&u,&v,&w);adde(u,v,w);adde(v,u,w);
38     }
39     for(int i=1;i<=m2;i++){
40         int u,v,w;scanf("%d%d%d",&u,&v,&w);adde(u,v,w);
41     }
42     memset(dis,0x3f,sizeof(dis));
43     spfa();
44     for(int i=1;i<=n;i++){
45         if(dis[i]==0x3f3f3f3f) printf("NO PATH\n");
46         else printf("%d\n",dis[i]);
47     }
48     return 0;
49 }
View Code

猜你喜欢

转载自www.cnblogs.com/plysc/p/10460097.html