【BZOJ】2200: [Usaco2011 Jan]道路和航线
【题意】给定n个点的图,正权无向边,正负权有向边,保证对有向边(u,v),v无法到达u,求起点出发到达所有点的最短距离。
【算法】拓扑排序+dijkstra
【题解】因为有负权边,直接对原图进行spfa,加slf优化后可过,但是这道题就没意思了。
理论上,最短路问题用spfa是不能保证复杂度的,但dijkstra的问题是不能处理负权边。
因为题目保证不能返回,实际上有向边将全图分成了几个部分。如果把仅由无向边连接的连通块看成点,则原图变成DAG。
对连通块内部进行dijkstra,在DAG上用拓扑序递推计算就可以保证O(n log n)出解。
具体实现:全图共用最短距离数组d[]。
对跨越连通块的有向边建新图,先用部分拓扑序删掉不从s出发的点。
开连通块个数的堆。
然后拓扑排序的过程中将到达别的连通块的点加入对应的堆,dijkstra时直接开始不用设置初始状态。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
using namespace std;
const int maxn=,inf=0x3f3f3f3f;
int first[maxn],FIRST[maxn],d[maxn],col[maxn],in[maxn],A[maxn],B[maxn];
int tot,cnt,n,m,N,M,s,color;
struct edge{int v,w,from;}e[maxn*],E[maxn*];
struct cyc{
int x,d;
bool operator < (const cyc &a)const{
return d>a.d;//
}
};
priority_queue<cyc>q[maxn];
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void INSERT(int u,int v,int w){cnt++;E[cnt].v=v;E[cnt].w=w;E[cnt].from=FIRST[u];FIRST[u]=cnt;in[v]++;}
void dfs(int x,int color){
col[x]=color;
for(int i=first[x];i;i=e[i].from)if(!col[e[i].v]){
dfs(e[i].v,color);
}
}
queue<int>Q;
void dijkstra(int k){
while(!q[k].empty()){
cyc y=q[k].top();q[k].pop();
if(y.d!=d[y.x])continue;
int x=y.x;
for(int i=first[x];i;i=e[i].from)if(d[e[i].v]>d[x]+e[i].w){
d[e[i].v]=d[x]+e[i].w;
q[k].push((cyc){e[i].v,d[e[i].v]});
}
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&M,&s);
for(int i=;i<=m;i++){
int u=read(),v=read(),w=read();
insert(u,v,w);insert(v,u,w);
}
for(int i=;i<=n;i++)if(!col[i])dfs(i,++N);
for(int i=;i<=M;i++){
int u=read(),v=read(),w=read();
INSERT(col[u],col[v],w);
A[i]=u;B[i]=v;
}
for(int i=;i<=N;i++)if(!in[i]&&col[s]!=i)Q.push(i);
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=FIRST[x];i;i=E[i].from){
in[E[i].v]--;
if(!in[E[i].v]&&col[s]!=E[i].v)Q.push(E[i].v);
}
}
Q.push(col[s]);
memset(d,0x3f,sizeof(d));d[s]=;q[col[s]].push((cyc){s,});
while(!Q.empty()){
int x=Q.front();Q.pop();
dijkstra(x);
for(int i=FIRST[x];i;i=E[i].from){
if(d[B[i]]>d[A[i]]+E[i].w){
d[B[i]]=d[A[i]]+E[i].w;
q[E[i].v].push((cyc){B[i],d[B[i]]});
}
in[E[i].v]--;
if(!in[E[i].v])Q.push(E[i].v);
}
}
for(int i=;i<=n;i++)if(d[i]<inf)printf("%d\n",d[i]);else printf("NO PATH\n");
return ;
}
dijkstra使用小根堆!每次加入距离最小的点。最致命的是写成大根堆也可以跑出答案,但是大数据就会很慢。
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
dijkstra使用小根堆!
【BZOJ】2200: [Usaco2011 Jan]道路和航线的更多相关文章
- [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- bzoj 2200: [Usaco2011 Jan]道路和航线——拓扑+dijkstra
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- BZOJ 2200: [Usaco2011 Jan]道路和航线
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- bzoj 2200: [Usaco2011 Jan]道路和航线【spfa】
直接跑最短路就行了--还不用判负环 #include<iostream> #include<cstdio> #include<queue> using namesp ...
- 2200: [Usaco2011 Jan]道路和航线 (拓扑排序+dijstra)
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- [Usaco2011 Jan]道路和航线
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- bzoj2200: [Usaco2011 Jan]道路和航线
先忽略航线,求出图中所有连通块,再用航线拓扑排序求出每个连通块的优先级 然后dijkstra时优先处理优先级高的块里的点就行了 ps:这题SPFA会TLE #include <iostream& ...
- BZOJ 2200--[Usaco2011 Jan]道路和航线(最短路&拓扑排序)
2200: [Usaco2011 Jan]道路和航线 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1128 Solved: 414[Submit] ...
- BZOJ 2199: [Usaco2011 Jan]奶牛议会
2199: [Usaco2011 Jan]奶牛议会 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 375 Solved: 241[Submit][S ...
随机推荐
- Android - TabHost 选项卡功能用法详解
TabHost效果图 : 源码下载地址 : http://download.csdn.net/detail/han1202012/6845105 . 作者 :万境绝尘 转载请注明出处 ...
- 【IdentityServer4文档】- 整体情况
整体概况 大多数现代应用程序看起来或多或少像这样: 最常见的交互是: 浏览器与 Web 应用程序进行通信 Web 应用程序与 Web API 进行通信(有时是Web应用程序自己发起,有时代表用户发起) ...
- java.lang.ClassNotFoundException: com.google.gson.Gson 问题解决
我是这么解决:把gson.jar放到WEB-INF/lib目录下. 放在其他目录就会报错.
- 《学习OpenCV》课后习题解答4
题目:(P104) 练习使用感兴趣区域(ROI).创建一个210*210的单通道图像并将其归0.在图像中使用ROI和cvSet()建立一个增长如金字塔状的数组.也就是:外部边界为0,下一个内部边界应该 ...
- 如何彻底解决adb 5037端口被占用
在进行安卓开发的时候是不是经常碰到adb端口被占用的情况? 解决这个问题的方法很简单,只需要设置一个系统环境变量就可以搞定. 设置方法: 增加系统环境变量变量名称:ADNROID_ADB_SERVER ...
- Android 如何判断CPU是32位还是64位
转自:http://blog.csdn.net/wangbaochu/article/details/47723265 1. 读取Android 的system property ("ro. ...
- spring cloud 之 客户端负载均衡 Ribbon
一.负载均衡 负载均衡(Load Balance): 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性.其意 ...
- 【python】python字符串前面加u,r,b的含义
1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用:后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出 ...
- bzoj4753[JSOI2016]最佳团体
题意:01分数规划,但可选的数字之间存在森林形的依赖关系(可以认为0号点是个虚根,因为并不能选). 虽然有森林形的依赖关系,但还是可以套分数规划的思路,二分答案k,判断是否存在一个比值大于k的方案 即 ...
- CentOS 文件搜索find
1.文件搜索,内置的的命令是find 用法: find [查找路径] 寻找条件 操作 默认路径为当前目录:默认表达式为 -print 2.主要参数: -name 匹配名称 -perm 匹配权限(mod ...