USACO 201 Jan. Gold
Farmer John 正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到 T 个城镇 ,编号为 1 到 T。这些城镇之间通过 R 条道路(编号为 1 到 R)和 P 条航线(编号为 1 到 P)连接。每条道路 i 或者航线 i 连接城镇 Ai 到 Bi,花费为 Ci。
对于道路,0 le C_i le 10^40≤Ci≤104,然而航线的花费很神奇,花费 Ci 可能是负数。道路是双向的,可以从 Ai 到 Bi,也可以从 Bi 到 Ai,花费都是 Ci。然而航线与之不同,只可以从 Ai 到 Bi。
事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策保证:如果有一条航线可以从 Ai 到 Bi,那么保证不可能通过一些道路和航线从 Bi 回到 Ai。由于 FJ 的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。他想找到从发送中心城镇 SS 把奶牛送到每个城镇的最便宜的方案,或者知道这是不可能的。
输入格式
第一行为四个空格隔开的整数:T,R,P,S;
第二到第 R+1 行:三个空格隔开的整数(表示一条道路):Ai,Bi 和 Ci;
第 R+2 到 R+P+1 行:三个空格隔开的整数(表示一条航线):Ai,Bi 和 Ci。
输出格式
输出 T 行,第 i 行表示到达城镇 i 的最小花费,如果不存在输出 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
样例说明
一共六个城镇。在 1 和 2,3 和 4,5 和 6 之间有道路,花费分别是 5,5,10。同时有三条航线:3→5,4→6 和 1→3,花费分别是 −100,−100,−10。FJ 的中心城镇在城镇 4。FJ 的奶牛从 4 号城镇开始,可以通过道路到达 3 号城镇。然后他们会通过航线达到 5 和 6 号城镇。但是不可能到达 1 和 2 号城镇。
数据范围与提示
对于全部数据,1≤T≤2.5×104,1≤R,P≤5×104,1≤Ai,Bi,S≤T。保证对于所有道路,0≤Ci≤104,对于所有航线,−104≤Ci≤104。
_______________________________________________________
有负边,明显SPFA。
超时,注意SPFA的优化。
_______________________________________________________
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=25010; 4 const int maxm=150010; 5 int n,r,p,s; 6 struct edge 7 { 8 int u,v,w,nxt; 9 }e[maxm]; 10 int head[maxn],js; 11 void addage(int u,int v,int w) 12 { 13 e[++js].u=u;e[js].v=v;e[js].w=w; 14 e[js].nxt=head[u];head[u]=js; 15 } 16 int dis[maxn]; 17 bool inq[maxn]; 18 void spfa(int x) 19 { 20 memset(dis,0x3f,sizeof dis); 21 inq[x]=1;dis[x]=0; 22 deque<int>q; 23 q.push_front(x); 24 while(!q.empty()) 25 { 26 int u=q.front(); 27 q.pop_front(); 28 inq[u]=0; 29 for(int i=head[u];i;i=e[i].nxt) 30 { 31 int v=e[i].v; 32 if(dis[v]>dis[u]+e[i].w) 33 { 34 dis[v]=dis[u]+e[i].w; 35 if(!inq[v]) 36 { 37 if(q.empty() || dis[v]<dis[q.front()])q.push_front(v); 38 else q.push_back(v); 39 inq[v]=1; 40 } 41 } 42 } 43 } 44 } 45 inline int read(){ 46 int ret=0;char ch=getchar();bool flg=0; 47 while(!isdigit(ch)) flg^=!(ch^'-'),ch=getchar(); 48 while(isdigit(ch)) ret=(ret<<3)+(ret<<1)+ch-48,ch=getchar(); 49 return flg?-ret:ret; 50 } 51 int main() 52 { 53 n=read();r=read();p=read();s=read(); 54 for(int u,v,w,i=0;i<r;++i) 55 { 56 u=read();v=read();w=read(); 57 addage(u,v,w);addage(v,u,w); 58 } 59 for(int u,v,w,i=0;i<p;++i) 60 { 61 u=read();v=read();w=read(); 62 addage(u,v,w); 63 } 64 spfa(s); 65 for(int i=1;i<=n;++i) 66 if(dis[i]==0x3f3f3f3f)puts("NO PATH"); 67 else printf("%d ",dis[i]); 68 return 0; 69 }