bzoj2200拓扑排序+最短路+联通块
自己写的不知道哪里wa了,明明和网上的代码差不多。,。
/*
给定一张图,有的边是无向边,有的是有向边,有向边不会出现在环中,且有可能是负权值
现在给定起点s,求出s到其余所有点的最短路长度
任何存在负权边的图都不可以用dij(有向图,无向图,有环图,无环图)
比如(1,2,8),(1,3,10)(3,2,-5),显然1-3的最短路径是5,但是dij求出的就是8
并且spfa超时 利用本题的无向边无 负权,且单向边不会出现在环中,先再每个联通块内求dij,然后用拓扑排序处理联通块之间的距离
先将所有无向边加入图,然后求出所有联通块,将联通块缩点
然后再加入有向边,按拓扑排序进行
算法流程:
1.把双向边加入图中,确定所有联通块,并染色
2.把单向边加入图中,确定所有的联通块的出度入度,只有S所在的联通块入度为0情况下才有解
3.开始拓扑排序,初始队列q中仅有c[S]联通块,同时建立dist数组,dist[s]=0
4.不断取出队头联通块,在联通块内进行堆优化的dij
a.把联通块内的所有结点加入堆
b.从堆中取出d[x]最小的结点,若x已经在最短路集合中,continue
c.遍历x的所有边(x,y,z),进行松弛
如果y是联通块内的,并且y被更新,则把y插入堆中
若y是其他联通块的,那么in[c[y]]--,如果减到了0,就把c[y]加入队尾
*/
#include<bits/stdc++.h>
#include<vector>
#include<queue>
using namespace std;
#define maxn 25005
#define maxm 50005
#define ll long long
struct Edge{int to,nxt,w,flag;}edge[maxm<<];
int head[maxn],tot,in[maxn],t,r,p,s;
void init(){
memset(head,-,sizeof head);
tot=;
}
void addedge(int u,int v,int w,int flag){
edge[tot].to=v;edge[tot].w=w;edge[tot].flag=flag;
edge[tot].nxt=head[u];head[u]=tot++;
} int c[maxn],cnt;
vector<int>vec[maxn];
void dfs(int u){//染色
c[u]=cnt;
vec[cnt].push_back(u);
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(c[v]==)dfs(v);
}
} int d[maxn],vis[maxn],used[maxn];
int main(){
while(cin>>t>>r>>p>>s){
init();
int u,v,w;
for(int i=;i<=r;i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w,);
addedge(v,u,w,);
} memset(c,,sizeof c);
for(int i=;i<=t;i++)
if(!c[i]){
cnt++;
vec[cnt].clear();
dfs(i);
} memset(in,,sizeof in);
for(int i=;i<=r;i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w,);
in[c[v]]++;
} memset(d,,sizeof d);
memset(used,,sizeof used);
memset(vis,,sizeof vis);
d[s]=; queue<int>q;
q.push(c[s]);//把s所在联通块入队
priority_queue<pair<int,int> >pq;
while(!q.empty()){
int u=q.front();q.pop();//从队头取出联通块
for(int i=;i<vec[u].size();i++){
int v=vec[u][i];
pq.push(make_pair(-d[v],v));
}
while(!pq.empty()){
int x=pq.top().second;pq.pop();
if(vis[x])continue;
vis[x]=;
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to,z=edge[i].w;
if(d[y]>d[x]+z){
if(c[x]==c[y]){
d[y]=d[x]+z;
pq.push(make_pair(-d[y],y));
}
}
if(c[x]!=c[y]){
d[y]=min(d[x]+z,d[y]);
in[c[y]]--;
if(in[c[y]]==)
q.push(c[y]);
}
}
}
}
for(int i=;i<=t;i++)
if(d[i]>0x3f3f3f3f)puts("NO PATH");
else printf("%d\n",d[i]);
}
}
网上的
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
const int N = ,M = , INF=0x3f3f3f3f; // M为双向边加单向边
int T,R,P,S,d[N];
int head[N],Next[M],ver[M],edge[M],tot;
bool v[N];
int c[N],totc,deg[N];
queue<int> q; // 联通块的拓扑序
priority_queue<pair<int, int> > Q; // Dij
void add(int x,int y, int z){
ver[++tot]=y, edge[tot]=z;
Next[tot]=head[x], head[x]=tot;
}
void dfs(int x){
for(int i=head[x]; i; i=Next[i]){
int y = ver[i];
if(!c[y]){
c[y]=totc;
dfs(y);
}
}
}
void Dijkstra(){
while(Q.size()){
int x = Q.top().second; Q.pop();
if(v[x])continue;
v[x] = ;
for(int i=head[x]; i; i=Next[i]){
int y = ver[i], wei = edge[i];
if(d[y] > d[x]+wei){
d[y] = d[x]+wei;
if(c[y]==c[x]) Q.push(make_pair(-d[y], y));
}
// 对遍历到的点,判断是否不同联通块
// 联通块入度减少,并且判0
if(c[x]!=c[y] && !--deg[c[y]])q.push(c[y]);
}
}
}
int main(){
cin>>T>>R>>P>>S;
int x,y,z;
fo(i,,R){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
// 划分联通块
fo(i,,T){
if(!c[i]){
c[i]=++totc;
dfs(i);
}
}
fo(i,,P){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
++deg[c[y]]; // 联通块的入度
}
// 联通块之间进行拓扑排序
q.push(c[S]); // 先加入起点
fo(i,,totc)if(!deg[i])q.push(i); // 加入0度的联通块
// topsort
memset(d, , sizeof(d)); // 这里最大值不能为0x3f,0x7f对应127
d[S] = ;
while(q.size()){
int i = q.front(); q.pop();
fo(j,,T)
if(c[j]==i)
Q.push(make_pair(-d[j], j)); // 联通块
Dijkstra();
}
fo(i,,T){
if(d[i]>INF)puts("NO PATH");
else printf("%d\n",d[i]);
}
}
bzoj2200拓扑排序+最短路+联通块的更多相关文章
- 牛客寒假训练营3 B 处女座的比赛资格(拓扑排序+最短路)
题目链接 这个题,一眼看上去就是最短路的题,边权有负环显然不能用dij,然后出题人又卡了spfa,,那怎么办的想点办法啊,好像还有一个拓扑排序可以求最短路吧,这时候正解就已经得到了,就是拓扑排序求最短 ...
- [luogu2149][bzoj1880][SDOI2009]Elaxia的路线【拓扑排序+最短路+DP】
题目描述 最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间 ...
- 【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法
Graph Search and Connectivity Generic Graph Search Goals 1. find everything findable 2. don't explor ...
- 【BZOJ2200】道路和航线(并查集,拓扑排序,最短路)
题意:n个点,有m1条双向边,m2条单向边,双向边边长非负,单向边可能为负 保证如果有一条从x到y的单项边,则不可能存在从y到x的路径 问从S出发到其他所有点的最短路 n<=25000,n1,m ...
- 【CSP模拟赛】益智游戏(最短路(DJSPFA)&拓扑排序)
题目描述 小P和小R在玩一款益智游戏.游戏在一个正权有向图上进行. 小P 控制的角色要从A 点走最短路到B 点,小R 控制的角色要从C 点走最短路到D 点. 一个玩家每回合可以有两种选择,移动到一个相 ...
- CodeForces 1213F (强联通分量分解+拓扑排序)
传送门 •题意 给你两个数组 p,q ,分别存放 1~n 的某个全排列: 让你根据这两个数组构造一个字符串 S,要求: (1)$\forall i \in [1,n-1],S_{pi}\leq S _ ...
- P3008 [USACO11JAN]Roads and Planes G (最短路+拓扑排序)
该最短路可不同于平时简单的最短路模板. 这道题一看就知道用SPFA,但是众所周知,USACO要卡spfa,所以要用更快的算法. 单向边不构成环,双向边都是非负的,所以可以将图分成若干个连通块(内部只有 ...
- Day3 最短路 最小生成树 拓扑排序
Day3 最短路 最小生成树 拓扑排序 (一)最短路 一.多源最短路 从任意点出发到任意点的最短路 1. Floyd \(O(n^3)\) for(int k=1;k<=n;k++) for(i ...
- [NOIP2017]逛公园 最短路+拓扑排序+dp
题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 ...
随机推荐
- 谈谈==和equals
== 先看Java /** * Author:Mr.X * Date:2017/10/8 23:17 * Description: * * @==判断两个内存地址是否相同 * @基础类型有(char, ...
- IDEA 启动时 自定义配置-只是看一下而已--注册激活
可以看到很多东西,比如 :Application Server 都这么类型 ============ ===== 2017年11月10日14:25:30 原来是这样注册的,号称最简单的 2017年11 ...
- Day17总结
1:登录注册案例(理解) 2:Set集合(理解) (1)Set集合的特点 无序,唯一 (2)HashSet集合(掌握) A:底层数据结构是哈希表(是一个元素为链表的数组) B:哈希表底层依赖两个方法: ...
- Android热更新技术——Tinker、nuwa、AndFix、Dexposed
一.热修复技术作用 线上app BUG紧急修复,不重新发版,不重新安装,在线远程修复问题 二.局限性与适用场景 补丁只能针对单一客户端版本,随着版本差异变大补丁体积也会增大: 补丁不能支持所有的修改, ...
- 启动项目时,mapper.xml文件没有导入
原因分析:绑定的statement没有发现,原因是只有mapper接口的java文件,没有xml文件 解决方法:需要在pom文件中进行配置 <!-- 如果不添加此节点mybatis的mapper ...
- Django实战(一)-----用户登录与注册系统1(环境搭建)
一.背景 学了一段时间的语法,总感觉入不了门,所以找点小项目练练手,项目来自网络. 二.创建虚拟环境,并安装Django 使用Python中的virtualenv搭建一个mysite_env全新的环境 ...
- Lock类-ReentrantLock的使用
在Java多线程中可以使用synchronized隐式锁实现线程之间同步互斥,Java5中提供了Lock类(显示锁)也可以实现线程间的同步,而且在使用上更加方便.本文主要研究 ReentrantLoc ...
- P2805 [NOI2009]植物大战僵尸
题目地址:P2805 [NOI2009]植物大战僵尸 最大权闭合子图 若有向图 \(G\) 的子图 \(V\) 满足: \(V\) 中顶点的所有出边均指向 \(V\) 内部的顶点,则称 \(V\) 是 ...
- SpringSecurity自定义用户认证逻辑
⒈处理用户信息获取逻辑 用户信息的获取逻辑是被SpringSecurity封装到UserDetailsService接口里面的 package org.springframework.security ...
- 【转】浅析Python中的struct模块
[转]浅析Python中的struct模块 最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概 ...