acdream1415(dij+优先队列+桥)
这题好坑,卡SPFA。。。
无奈只能用dij+优先队列了。 因为好久没有写过代码了,所以今天写dij时候突然觉得复杂度不对,dij+优先队列的复杂度是(n+m)logn,这种复杂度对于稠密图是非常慢!,而且还有超内存的可能(最坏情况要把n*n个点都存进优先队列),与我以前记得复杂度是nlogn不一样。。。 瞬间吓尿。
其实事实确实是这样,在采用斐波那契堆+dij时,斐波那契堆是插入复杂度为O(1),所以复杂度为nlogn+m,而普通我们用的STL种的priority_queue插入查询复杂度都是logn,所以总的复杂度为(n+m)logn.
所以,dij+优先队列虽然方便好写,但只适用用稀疏图,也就是m小的时候。
最后关于这题的思路,求一次从1开始到其他所有点的最短距离diss[i],再求一次从n开始到其他所有点的最短距离dist[i],然后如果边 <u,v>w 满足diss[u]+w+dist[v]=min(其中min是1到n的最短距离)说明这条边,绝对在一条最短路线中。 这样把所有这样的边找出来,并重新构图,那么只要找出这个图中的桥,并且满足1,n分别在桥的两端。
Important Roads
Problem Description
The city where Georgie lives has n junctions some of which are connected by bidirectional roads.
Every day Georgie drives from his home to work and back. But the roads in the city where Georgie lives are very bad, so they are very often closed for repair. Georgie noticed that when some roads are closed he still can get from home to work in the same time as if all roads were available.
But there are such roads that if they are closed for repair the time Georgie needs to get from home to work increases, and sometimes Georgie even cannot get to work by a car any more. Georgie calls such roads important.
Help Georgie to find all important roads in the city.
Input
The first line of the input file contains n and m — the number of junctions and roads in the city where Georgie lives, respectively (2 ≤ n ≤ 20 000, 1 ≤ m ≤ 100 000). Georgie lives at the junction 1 and works at the junction n.
The following m lines contain information about roads. Each road is specified by the junctions it connects and the time Georgie needs to drive along it. The time to drive along the road is positive and doesn’t exceed 100 000. There can be several roads between a pair of junctions, but no road connects a junction to itself. It is guaranteed that if all roads are available, Georgie can get from home to work.
Output
Sample Input
6 7
1 2 1
2 3 1
2 5 3
1 3 2
3 5 1
2 4 1
5 6 2
Sample Output
2
5 7
Source
Manager
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <stdlib.h>
#include <queue>
using namespace std;
#define M 100100
#define N 20020
#define INF 0x3fffffffff int n,m;
struct node
{
int from,to,next,w,id;
}edge[*M]; struct node1
{
long long w;
int id;
bool operator < (const node1 t)const
{
return t.w<w;
}
}; int pre[N],cnt;
long long int diss[N],dist[N];
int que[M+];//用循环队列怎么样
int ans,save[M];
//然后就是找桥了 priority_queue<node1> pque; int len[N],mark[M];
int index1; void add_edge(int u,int v,int w,int id)
{
edge[cnt].from=u;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].id=id;
edge[cnt].next=pre[u];
pre[u]=cnt++;
} void dij(long long int dis[N],int s)
{
memset(mark,,sizeof(mark));
while(pque.size()!=) pque.pop(); for(int i=;i<=n;i++)
dis[i]=INF; dis[s]=;
node1 fi;
fi.id=s;
fi.w=;
pque.push(fi);
//我就说, 用优先队列优化,对于稠密图基本没意义
node1 nwnode,cur;
while(pque.size()!=)
{
cur = pque.top();
pque.pop();
if(mark[cur.id]==) continue;
int u=cur.id;
mark[u]=;
for(int p=pre[u];p!=-;p=edge[p].next)
{
int v=edge[p].to;
if(mark[v]==) continue;
if(dis[v]>cur.w+edge[p].w)
{
dis[v]=cur.w+edge[p].w;
nwnode.id=v;
nwnode.w=dis[v];
pque.push(nwnode);
}
}
}
} void spfa(long long int dis[N],int s,int t)
{
//SPFA都忘记怎么写了
memset(mark,,sizeof(mark));
for(int i=;i<=n;i++)
{
dis[i]=INF;
} int qf=,qd=;
que[qf]=s;
qf++; dis[s]=;
mark[s]=; while(qf!=qd)//作为一个循环队列,
{
int cur=que[qd];
qd=(qd+)%M;
mark[cur]=;
for(int p=pre[cur];p!=-;p=edge[p].next)
{
int v = edge[p].to;
if( dis[v]>dis[cur] + edge[p].w )
{
dis[v]=dis[cur]+edge[p].w;
if(mark[v]==)
{
que[qf]=v;
qf=(qf+)%M;
mark[v]=;
}
}
}
}
} void dfs(int s)
{
//len[s]==-1表示没来过 len[s]=index1++;
int tmp = len[s];
for(int p=pre[s];p!=-;p=edge[p].next)
{
int v=edge[p].to;
if( mark[edge[p].id]== ) continue; if(len[v]==-)
{
mark[edge[p].id]=;//把这条边标记了
dfs(v);
tmp=min(tmp,len[v]);
if(len[v]>len[s])//这个就是桥
{
if(len[n]!=-)
{
if(len[]<=len[s]&&len[n]>=len[v])
{
save[ans++]=edge[p].id;
}
}
}
}//无向图的桥怎么求。。。,忘光了。
else
{
tmp=min(tmp,len[v]);
}
} len[s]=tmp;
} int main()
{
scanf("%d%d",&n,&m);
cnt=;
memset(pre,-,sizeof(pre)); for(int i=;i<=m;i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
add_edge(x,y,w,i);
add_edge(y,x,w,i);
} //卡SPFA???
//去你妹的 //spfa(diss,1,n);
//spfa(dist,n,1); dij(diss,);
dij(dist,n); long long int mi=diss[n]; //最短距离
int tcnt = cnt; cnt=;
memset(pre,-,sizeof(pre)); for(int i=;i<tcnt;i+=)
{
int x,y,w,id;
x=edge[i].from;
y=edge[i].to;
w=edge[i].w;
id=edge[i].id;
if( diss[x]+dist[y]+w ==mi || dist[x] + diss[y]+w==mi )
{
add_edge(x,y,w,id);
add_edge(y,x,w,id);
}
}
//构建了一个由所有可能最短路边构成的图
memset(mark,,sizeof(mark)); //感觉要用来记录边比较好
memset(len,-,sizeof(len));
index1=;
ans = ; dfs();
printf("%d\n",ans);
if(ans!=)
{
for(int i=;i<ans-;i++)
printf("%d ",save[i]);
printf("%d\n",save[ans-]);
}
return ;
}
acdream1415(dij+优先队列+桥)的更多相关文章
- L2-020. 功夫传人(dfs+vector 或者 邻接矩阵+dij+优先队列)
L2-020. 功夫传人 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一门武功能否传承久远并被发扬光大,是要看缘分的.一般来 ...
- HDU6582 Path【优先队列优化最短路 + dinic最大流 == 最小割】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 来源:2019 Multi-University Training Contest 1 题目大意 ...
- hdu3986 spfa+枚举
这题让我第一次感受到了什么叫做在绝望中A题.这题我总共交了18次,TLE不知道几次,WA也不知道几次. 这题不能用dijkstra,用这个我一直超时(我没试过dij+优先队列优化,好像优先队列优化后可 ...
- 洛谷题解 P2865 【[USACO06NOV]路障Roadblocks】
链接:https://www.luogu.org/problemnew/show/P2865 题目描述 Bessie has moved to a small farm and sometimes e ...
- codeforces 821 D. Okabe and City(最短路)
题目链接:http://codeforces.com/contest/821/problem/D 题意:n*m地图,有k个位置是点亮的,有4个移动方向,每次可以移动到相邻的点亮位置,每次站在初始被点亮 ...
- poj3013 邻接表+优先队列+Dij
把我坑到死的题 开始开题以为是全图连通是的最小值 ,以为是最小生成树,然后敲了发现不是,看了下别人的题意,然后懂了: 然后发现数据大,要用邻接表就去学了一下邻接表,然后又去学了下优先队列优化的dij: ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 优先队列+dij
1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1768 Solv ...
- dij的优先队列边表优化
dij的复杂度为v*v,通过优先队列优化后为e*logv. (第一次写,没有过多的测试,不保证对.只当是测试blog了!) #include<cstdio> #include<ios ...
- dij最短路优先队列堆的时候,加边
不能用全局数组d[u]>d[rhs.u]. 这样后面会修改d[u]值然而本来里面的点顺序不该修改,却被修改了. 应该用栈还存进去的临时变量,比如d>rhs.d. 优先队列重载小于号'< ...
随机推荐
- No enclosing instance of type Demo is accessible. Must qualify the allocation with an enclosing instance of type Demo (e.g. x.new A() where x is an instance of Demo).
No enclosing instance of type Demo is accessible. Must qualify the allocation with an enclosing inst ...
- Mac系统使用命令行快捷打开Sublime
本篇文章由:http://xinpure.com/use-command-line-shortcuts-to-open-the-mac-system-sublime/ 方法一 使用软链接 ln -s ...
- C# EF使用性能消耗列表 https://msdn.microsoft.com/zh-cn/library/cc853327.aspx
性能注意事项(实体框架) .NET Framework (current version) 其他版本 本主题介绍 ADO.NET 实体框架的性能特征,并提供一些注意事项帮助改善实体框架应用程序 ...
- centos(7.0) 上 crontab 计划任务
yum install vixie-cron yum install crontabs /bin/systemctl restart crond.service #启动服务 /bin/systemc ...
- 消息队列 概念 配合SpringBoot使用Demo
转http://www.jianshu.com/p/048e954dab40 概念: 分布式消息队列 ‘分布式消息队列’包含两个概念 一是‘消息队列’,二是‘分布式’ 那么就先看下消息队列的概念,和为 ...
- redis安装和配置(一)
Redis 的官方下载站是http://redis.io/download 怎么安装 Redis 数据库呢?下面将介绍Linux 版本的安装方法 步骤一: 下载Redis 下载安装包:wget htt ...
- 【ZYNQ-7000开发之九】使用VDMA在PL和PS之间传输视频流数据
[ZYNQ-7000开发之九]使用VDMA在PL和PS之间传输视频流数据 原创 2016年01月14日 11:35:02 标签: VDMA / zynq / zedbaord / AXI 10384 ...
- HTTP 用户认证
HTTP 常见的用户认证可以分为下面三种: 基于IP,子网的访问控制(ACL) 基本用户验证(Basic Authentication) 消息摘要式身份验证(Digest Authentication ...
- TCP协议的三次握手和四次挥手过程
TCP是一种面向连接(连接导向)的.可靠的基于字节流的传输层通信协议.TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认.对失序的数据重新排序.丢弃重复数据. 1.TCP/ ...
- java 发送带Basic Auth认证的http post请求实例代码
构造http header private static final String URL = "url"; private static final String APP_KEY ...