博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 2725 故乡的梦 (删边最短路)
阅读量:7214 次
发布时间:2019-06-29

本文共 3932 字,大约阅读时间需要 13 分钟。

题目链接:

题意:给出一个带权无向图,起点S和终点T。Q个询问。每个询问询问删除某条边后S到T的最短路。

思路:

(1)计算每个点到S和T的最短路;

(2)记录最短路用到的边,这些边构成一个新图;

(3)求出新图上的桥,桥将新图分成若干连通块(其实所有的连通块是线性排列的);

(4)对于删除的边若不是新图中的桥无视;否则,枚举这个桥连接的两个连通块的所有边,并用这些边(u,v)的权+disS[u]+disT[v]作为排序关键字对边排序,最小的即是答案。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define abs(x) ((x)>=0?(x):-(x))#define i64 long long#define u32 unsigned int#define u64 unsigned long long#define clr(x,y) memset(x,y,sizeof(x))#define pb(x) push_back(x)#define SZ(x) x.size()#define PI acos(-1.0)#define sqr(x) ((x)*(x))using namespace std;struct node{ int v,next; i64 dis; node(){} node(int _v,i64 _dis) { v=_v; dis=_dis; } friend bool operator<(node a,node b) { return a.dis>b.dis; }};const i64 INF=((i64)1)<<62;const int MAXN=200005;const int MAXE=1000005;node edges[MAXE];int head[MAXN],begin[MAXN],end[MAXN],query[MAXN],e;int Qu[MAXN],Qv[MAXN];i64 disS[MAXN],disT[MAXN],ans[MAXN];int n,m,S,T,visit[MAXE];int shy[MAXN<<1],imp[MAXN<<1];int low[MAXN],dfn[MAXN],id,father[MAXN];int color[MAXN],colorNum;int go[MAXN],rank[MAXN],f[MAXE];priority_queue
Q;void init(){ clr(head,-1); clr(begin,-1); clr(end,-1); clr(query,-1); clr(imp,0); clr(low,0); clr(dfn,0); clr(color,0); clr(go,0); clr(rank,0); clr(ans,-1); e=2; id=0; colorNum=0;}void Add1(int u,int v,i64 dis){ edges[e].v=v; edges[e].dis=dis; edges[e].next=head[u]; head[u]=e++;}void Dij(int s,i64 dis[]){ int i,u,v; node p,q; for(i=0;i<=n;i++) dis[i]=INF; while(!Q.empty()) Q.pop(); Q.push(node(s,0)); dis[s]=0; while(!Q.empty()) { p=Q.top(); Q.pop(); u=p.v; for(i=head[u];i!=-1;i=edges[i].next) { v=edges[i].v; if(dis[v]>p.dis+edges[i].dis) { dis[v]=p.dis+edges[i].dis; Q.push(node(v,dis[v])); } } }}void BFS(int s){ clr(shy,0); clr(visit,0); queue
Q; int i,u,v; Q.push(s); visit[s]=1; while(!Q.empty()) { u=Q.front(); Q.pop(); for(i=head[u];i!=-1;i=edges[i].next) { v=edges[i].v; if(disS[v]==disS[u]+edges[i].dis) { shy[i]=1; shy[i^1]=2; if(visit[v]) continue; Q.push(v); visit[v]=1; } } }}void DFS(int u){ color[u]=colorNum; int i,v; for(i=head[u];i!=-1;i=edges[i].next) { v=edges[i].v; if(shy[i]==1&&!color[v]) DFS(v); }}int Tarjan(int u){ int p=(u==T),i,v; dfn[u]=low[u]=++id; for(i=head[u];i!=-1;i=edges[i].next) if(shy[i]==1) { v=edges[i].v; if(!dfn[v]) { father[v]=i; if(Tarjan(v)) { low[u]=min(low[u],low[v]); p=1; } } else if(father[u]!=i^1) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]&&p) { colorNum++; DFS(u); if(father[u]) { v=father[u]; imp[v]=shy[v]; v=father[u]^1;imp[v]=shy[v]; } } return p;}void Add2(int u,int v){ edges[e].v=v; edges[e].next=begin[u]; begin[u]=e++;}void Add3(int u,int v){ edges[e].v=v; edges[e].next=end[u]; end[u]=e++;}void Add4(int u,int v){ edges[e].v=v; edges[e].next=query[u]; query[u]=e++;}void buildGraph(){ int i,j,v,x,y; for(i=2;i
rank[y]) swap(Qu[i],Qv[i]); Add4(color[Qu[i]],i); }}i64 dat(int a){ int u=edges[a^1].v; int v=edges[a].v; return disS[u]+edges[a].dis+disT[v];}int cmp(int a,int b){ return dat(a)>dat(b);}void solve(){ clr(visit,0); int i,j,k,p=0,v; for(i=color[S];i;i=go[i]) { for(j=end[i];j!=-1;j=edges[j].next) { v=edges[j].v; visit[v]=1; } for(j=begin[i];j!=-1;j=edges[j].next) { v=edges[j].v; if(!imp[v]) f[++p]=v,push_heap(f+1,f+p+1,cmp); else k=v; } while(p&&visit[f[1]]) pop_heap(f+1,f+p+1,cmp),p--; for(j=query[i];j!=-1;j=edges[j].next) { v=edges[j].v; if(Qu[v]==edges[k^1].v&&Qv[v]==edges[k].v) { ans[v]=p?dat(f[1]):-1; } else { ans[v]=disS[T]; } } }}int main(){ while(scanf("%d%d",&n,&m)!=-1) { init(); int i,u,v,d; for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&d); Add1(u,v,d); Add1(v,u,d); } scanf("%d%d%d",&S,&T,&m); Dij(S,disS); Dij(T,disT); BFS(S); Tarjan(S); buildGraph(); solve(); for(i=1;i<=m;i++) { if(ans[i]==-1) puts("Infinity"); else printf("%lld\n",ans[i]); } } return 0;}

  

转载地址:http://dsyym.baihongyu.com/

你可能感兴趣的文章
LAMP自动安装脚本(上)
查看>>
安全规范和指南系列之二
查看>>
IT草根的江湖之路之七: 挑战,刚刚开始
查看>>
总结之:CentOS6.5 DNS服务BIND配置、正反向解析、主从及压力测试(1)
查看>>
Spring Security(16)——基于表达式的权限控制
查看>>
Oracle中的LOB数据类型以及ibatis中处理该类型的typeHandler
查看>>
917:Knight Moves
查看>>
【IT基础】windows核心编程整理(上)
查看>>
[arm驱动]linux并发与竞态---并发控制
查看>>
jailkit 限制用户活动范围和权限
查看>>
WMI技术的使用
查看>>
Socket编程实践(10) --select的限制与poll的使用
查看>>
Unix Study之--AIX安装和配置SSH
查看>>
转:iPhone之后,思考下一个科技突破(之二)
查看>>
如何将Ant下Web项目迁移到Hudson实现持续化集成开发
查看>>
avascript解汉诺塔问题
查看>>
三种快速以太网标准
查看>>
Waymo乘客交互系统亮相,还带西方记者试乘了没司机的真·无人车
查看>>
IPv4和IPv6共存技术---ISATAP隧道
查看>>
【Cocoa(mac) Application 开发系列之二】总结一些常用控件及自定义View
查看>>