bzoj 2200 道路与航线 最短路进阶
2015-05-17 16:39
330 查看
2200: [Usaco2011 Jan]道路和航线
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 528 Solved: 173
[Submit][Status][Discuss]
Description
Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T。这些城镇之间通过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_iOutput
* 第1到T行:从S到达城镇i的最小花费,如果不存在输出"NO PATH"。Sample Input
6 3 3 41 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 PATHNO PATH
5
0
-95
-100
样例输出解释:
FJ的奶牛从4号城镇开始,可以通过道路到达3号城镇。然后他们会通过航线达到5和6号城镇。
但是不可能到达1和2号城镇。
wa了无数遍,最终发现bfs算入度的时候没标记起点,啊啊~~错的萌萌哒~~
题意:在一个含有向边(存在负边),无向边的图中,给你一个起点,求出起点到所有点的最短路,
有负边,spfa搞。。超时,堆优化的dijkstra不能处理负边~~。
思路:由于题目说了,如果有A到B的航线,不会有B到A的航线或道路。就是说不会存在含有 有向边的环。所以我们把所有的无向边的点缩点,缩点后会发现此图变成一个有向无环图,对于有向无环图我们可以top序dp求出起点到每个连通块的最短路。然后在每个连通块中用dijkstra求最短路,就行了。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define MAX 25005 #define mod 10000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)1 using namespace std; typedef long long ll; struct edge { int v,w; edge(int _v,int _w) : v(_v),w(_w) {} }; struct node { int u,d; node (int _u,int _d): u(_u),d(_d) {} bool operator <(const node & a) const { return a.d<d; } }; vector<edge> plan[MAX*4],road[MAX*4]; int pre[MAX],dis[MAX],vis[MAX],degree[MAX]; int find(int r) { return pre[r] == r ? r : (pre[r] = find(pre[r])); } void ol(int n) { for(int i=1; i<=n; i++) pre[i]=i; for(int i=1; i<=n; i++) { int len=road[i].size(); for(int j=0; j<len; j++) { int x=find(i); int y=find(road[i][j].v); if(x!=y) pre[x]=y; } } } int used[MAX]; void bfs(int s) { queue<int> de; de.push(s); used[s]=1; while(!de.empty()) { int u=de.front(); de.pop(); int lenr=road[u].size(); for(int i=0; i<lenr; i++) { int v=road[u][i].v; if(!used[v]) { used[v]=1; de.push(v); } } int lenp=plan[u].size(); for(int i=0; i<lenp; i++) { int v=plan[u][i].v; ++degree[find(v)]; if(!used[v]) { used[v]=1; de.push(v); } } } } priority_queue<node> q; vector<int>go[MAX]; queue<int> dp; void dijkstra(int s) { while(!q.empty()) q.pop(); for(int i=0; i<go[s].size(); i++) { int v=go[s][i]; q.push(node(v,dis[v])); } while(!q.empty()) { node tmp=q.top(); q.pop(); int u=tmp.u; if(vis[u]) continue; vis[u]=1; int lenr=road[u].size(); for(int i=0; i<lenr; i++) { int v=road[u][i].v; int w=road[u][i].w; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; q.push(node(v,dis[v])); } } int len=plan[u].size(); for(int i=0; i<len; i++) { int v=plan[u][i].v; int w=plan[u][i].w; int root=find(v); if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; go[root].push_back(v); } --degree[root]; if(degree[root]==0) dp.push(root); } } } void top_dp(int s) { while(!dp.empty()) dp.pop(); dp.push(find(s)); go[find(s)].push_back(s); while(!dp.empty()) { int now=dp.front(); dp.pop(); dijkstra(now); } } void init() { CLR(degree,0); CLR(vis,0); CLR(used,0); } int main() { int n,r,p,s,u,v,w; init(); scanf("%d%d%d%d",&n,&r,&p,&s); CLR(dis,0x3f); dis[s]=0; for(int i=1; i<=r; i++) { scanf("%d%d%d",&u,&v,&w); road[u].push_back(edge(v,w)); road[v].push_back(edge(u,w)); } ol(n); for(int i=1; i<=p; i++) { scanf("%d%d%d",&u,&v,&w); plan[u].push_back(edge(v,w)); } bfs(s); top_dp(s); for(int i=1; i<=n; i++) { if(dis[i]==INF) printf("NO PATH\n"); else printf("%d\n",dis[i]); } return 0; }
相关文章推荐
- bzoj2200 [Usaco2011 Jan]道路和航线 最短路
- bzoj2200道路和航线
- BZOJ 2200 道路与航线
- 【BZOJ】2200: [Usaco2011 Jan]道路和航线
- 【BZOJ】【2200】【USACO 2011 Jan】道路和航线
- BZOJ 2200 [Usaco2011 Jan]道路和航线
- bzoj 2200: [Usaco2011 Jan]道路和航线【spfa】
- BZOJ 2200: [Usaco2011 Jan]道路和航线
- bzoj 2200: [Usaco2011 Jan]道路和航线——拓扑+dijkstra
- [BZOJ2200][Usaco2011 Jan]道路和航线
- BZOJ2200: [Usaco2011 Jan]道路和航线
- bzoj1579 [Usaco2009 Feb]Revamping Trails 道路升级(分层图最短路)
- 【BZOJ 1579】 1579: [Usaco2009 Feb]Revamping Trails 道路升级 (最短路)
- 分层图最短路 【bzoj1579】[Usaco2009 Feb]Revamping Trails 道路升级
- BZOJ 1579: [Usaco2009 Feb]Revamping Trails 道路升级 分层图最短路
- BZOJ 1579: [Usaco2009 Feb]Revamping Trails 道路升级( 最短路 )
- BZOJ_1579_[Usaco2009 Feb]Revamping Trails 道路升级_分层图最短路
- bzoj 3575: [Hnoi2014]道路堵塞 最短路
- 【bzoj1579/Usaco2009 Feb】Revamping Trails 道路升级——分层图最短路
- [BZOJ1579] [Usaco2009 Feb]Revamping Trails 道路升级(分层图最短路 + 堆优化dijk)