BZOJ 2725 [Violet 6]故乡的梦
来源:互联网 发布:淘宝网牛仔裤女款 编辑:程序博客网 时间:2024/05/01 02:29
堆优dijkstra+线段树
膜:http://blog.csdn.net/popoqqq/article/details/47841783
为了表达清楚,记不删边时最短路为E1,删去某一条E1上的边之后的最短路为E2
显然E2一定是形如:S->沿着E1走到某一个在E1上点的S’->沿着不属于E1的一些边走到某一在E1上点的T’->沿着E1走到T
而且可以证明,上面提到的E2中不属于E1的那些边(组成一条路径)中,一定存在至少一条边,记它的两端点为u,v,使得E2上沿着S->u的路径是S->u在原图中的最短路,E2上沿着v->T的路径是v->T在原图中的最短路。
这个可以通过反证法证明,前提是原图为无向图。
然而其实这一题我并没有AC。。。不知道是因为复杂度退化了还是常数太大了,一直T。。。
#include<map>#include<cstdio>#include<cstring>#include<algorithm>#define N 200005#define cmin(u,v) (u)>(v)?(u)=(v):0#define mkp(a,b) (1ll*a*N+b)#define reg registerusing namespace std;int in(){ register long long r = 0; register char c = getchar(); while(c<'0'||c>'9')c = getchar(); while(c>='0'&&c<='9')r = r*10+c-'0', c=getchar(); return r;}char ss[100];inline void out(long long x){ if(x==0) {putchar(48); return;} char *s=ss; while(x) *(++s)=x%10, x/=10; while(s!=ss) putchar((*(s--))+48); putchar('\n');}map<long long,bool> PathEdge;map<long long,int> PathId;struct node{ int id; long long dis; node(){} node(int a, long long b):id(a),dis(b){}}heap[N<<1];struct Segment_tree{ int l, r; long long val, lazy;}t[N*5];struct edge{int from,next,to, val;}e[N<<1];const long long INF = 1ll<<61;long long dis[N], ds[N], dt[N], print[N];int n, last[N], ecnt=1, fa[N], fs[N], ft[N], ll[N], rl[N], mapp[N], tcnt, ct[N], ctt, tot;bool vis[N], PathPoint[N];void addedge(int a, int b, int c){ e[++ecnt]=(edge){a,last[a],b,c}; last[a]=ecnt; PathId[mkp(a,b)]=ecnt;}void heap_add(node x){ heap[++tot]=x; for(reg int i=tot,j=i>>1;j;i=j,j>>=1) { if(heap[j].dis>heap[i].dis) swap(heap[j],heap[i]); else break; }}void heap_pop(){ heap[1]=heap[tot--]; for(reg int i=1,j=i<<1;j<=tot;i=j,j<<=1) { if(j<tot&&heap[j].dis>heap[j|1].dis)j|=1; if(heap[j].dis<heap[i].dis) swap(heap[j],heap[i]); else break; }}void dijk(int s){ memset(vis,0,sizeof(vis)); memset(dis,0x7f,sizeof(dis)); heap_add(node(s,dis[s]=0)); while(tot) { int x=heap[1].id; heap_pop(); if(vis[x])continue; vis[x]=1; for(reg int i = last[x]; i; i=e[i].next) { int y=e[i].to; if(vis[y] || dis[x]+e[i].val>=dis[y])continue; dis[y]=dis[x]+e[i].val; fa[y]=x; heap_add(node(y,dis[y])); } }}void dijk2(int s, int *fs, long long *ds){ memset(vis,0,sizeof(vis)); memset(ds,0x7f,sizeof(dis)); heap_add(node(s,ds[s]=0)); while(tot) { int x=heap[1].id; heap_pop(); if(vis[x])continue; vis[x]=1; if(PathPoint[fa[x]] && (!PathPoint[x])) fs[x]=fa[x]; else if(PathPoint[x])fs[x]=x; else fs[x]=fs[fa[x]]; for(reg int i = last[x]; i; i=e[i].next) { int y=e[i].to; if(vis[y] || ds[x]+e[i].val>=ds[y])continue; ds[y]=ds[x]+e[i].val; fa[y]=x; heap_add(node(y,ds[y])); } } }void pushdown(int x){ cmin(t[x<<1].val,t[x].lazy); cmin(t[x<<1|1].val,t[x].lazy); cmin(t[x<<1].lazy,t[x].lazy); cmin(t[x<<1|1].lazy,t[x].lazy); t[x].lazy=INF;}void merge(int x){ cmin(t[x].val,t[x<<1].val); cmin(t[x].val,t[x<<1|1].val);}void build(int x, int l, int r){ t[x].l=l; t[x].r=r; t[x].val=INF; t[x].lazy=INF; if(l==r)return; int mid=(l+r)>>1; build(x<<1,l,mid); build(x<<1|1,mid+1,r);}void update(int x, int l, int r, long long v){ pushdown(x); if(l<=t[x].l && t[x].r<=r) { cmin(t[x].val,v); cmin(t[x].lazy,v); return; } int mid=(t[x].l+t[x].r)>>1; if(l<=mid)update(x<<1,l,r,v); if(mid+1<=r)update(x<<1|1,l,r,v); merge(x);}void ask(int x){ pushdown(x); if(t[x].l==t[x].r) { print[t[x].l]=t[x].val; return; } ask(x<<1); ask(x<<1|1);}int main(){ int m, s, t, Q; n=in();m=in(); for(reg int i = 1, a, b, c; i <= m; i++) { a=in(); b=in(); c=in(); addedge(a,b,c); addedge(b,a,c); } s=in(); t=in(); Q=in(); dijk(s); PathPoint[s]=1; for(reg int pos = t; fa[pos]; pos=fa[pos]) { ct[pos]=++ctt; PathPoint[pos]=1; PathEdge[mkp(pos,fa[pos])]=1; PathEdge[mkp(fa[pos],pos)]=1; ll[pos]=PathId[mkp(fa[pos],pos)]>>1; rl[fa[pos]]=PathId[mkp(fa[pos],pos)]>>1; mapp[ll[pos]]=++tcnt; } ct[s]=++ctt; fa[s]=0;dijk2(s,fs,ds); fa[t]=0;dijk2(t,ft,dt); build(1,1,ecnt>>1); for(reg int i = 2; i <= ecnt; i+=2) { int a=e[i].from, b=e[i].to, val=e[i].val; if(!PathEdge[mkp(a,b)]) { if(mapp[ll[ft[b]]] && mapp[ll[ft[b]]]<=mapp[rl[fs[a]]])update(1,mapp[ll[ft[b]]],mapp[rl[fs[a]]],ds[a]+dt[b]+val); if(mapp[ll[ft[a]]] && mapp[ll[ft[a]]]<=mapp[rl[fs[b]]])update(1,mapp[ll[ft[a]]],mapp[rl[fs[b]]],ds[b]+dt[a]+val); } } if(dis[t]>=INF) { for(;Q--;) printf("Infinity\n"); return 0; } memset(print,0x7f,sizeof(print)); ask(1); for(;Q--;) { int a=in(), b=in(); if(!PathEdge[mkp(a,b)])printf("%lld\n",dis[t]); else { if(ct[a]<ct[b])swap(a,b); long long ans = print[mapp[ll[ft[b]]]]; if(ans==INF)printf("Infinity\n"); else printf("%lld\n",ans); } }}
0 0
- BZOJ 2725 [Violet 6]故乡的梦
- bzoj 2725 [Violet 6]故乡的梦
- BZOJ 2725 [Violet 6]故乡的梦 最短路
- 2725: [Violet 6]故乡的梦
- BZOJ 2725 Violet 6 故乡的梦 堆优化Dijkstra+线段树
- bzoj 2725: [Violet 6]故乡的梦 堆优化Dijkstra+线段树
- BZOJ2725 [Violet 6]故乡的梦
- [删边最短路 并查集||线段树] BZOJ 2725 [Violet 6]故乡的梦 & 4400 tjoi2012 桥
- bzoj2725: [Violet 6]故乡的梦&&bzoj4400: tjoi2012 桥
- [bzoj 2725] 故乡的梦
- bzoj2725 [Violet 6] 故乡的梦 && 4400 tjoi2012 桥 Dijkstra+线段树
- 【BZOJ 2724】 [Violet 6]蒲公英
- bzoj 2724: [Violet 6]蒲公英
- Bzoj 2724 [Violet 6]蒲公英
- BZOJ 2724 [Violet 6]蒲公英
- BZOJ 2724 [Violet 6] 蒲公英
- BZOJ 2724: [Violet 6]蒲公英
- 【BZOJ】【P2724】【Violet 6】【蒲公英】【题解】【分块】
- WebBench测试源码解析
- levelDB immutable Table的文件格式
- All X(快速幂 + 循环节)
- jzoj 4820. 【NOIP2016提高A组模拟10.15】最大化 动态规划+单调队列+二分
- 缓存与数据库一致性保证
- BZOJ 2725 [Violet 6]故乡的梦
- Java Web 工作原理
- 2017去哪儿java开发工程师及编程题答案
- hdu2552三足鼎立+数学推论
- Octave学习之入门第一天
- 序列化和反序列化
- 【USACO题库】2.4.5 Fractions to Decimals分数化小数
- 时间序列分析--指数平滑法
- 讨论Bitmap.config参数