bzoj 2725 [Violet 6]故乡的梦
来源:互联网 发布:java手机网游有哪些 编辑:程序博客网 时间:2024/05/01 03:43
无向图,给定S和T,多次询问在删除某条边时两点间最短路
我的SPFA被卡了=.=。我们对所有不在最短路径的上的边 ,设它的起点为u 终点为v。那么对于这条边,包含该边的最优的S到T路径就应该是 S-S1-u-v-T1-T 其中S1,T1表示最短路径上的两个点。那么这样的一条最短路可以再S1-T1中某条边被删除时使用,我们用线段树维护这一过程 QWQ 数组开多了有点晕啊
#include<iostream>#include<algorithm>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#include<queue>using namespace std;const int maxn=400000+10;typedef long long LL;struct tree{int l,r;LL s,lazy;}t[maxn<<2];struct node{int to,next;LL len;int fr;bool o;}table[maxn<<1];int tot=1,head[maxn];void add(int a,int b,int c){table[++tot]=(node){b,head[a],c,a};head[a]=tot;}int n,m,S,T,Q;char s[1<<25];inline long long read(){ static char *c=s; if(c==s) fread(c,1,1<<25,stdin); long long u=0; while(*c<48) ++c; while(*c>32) u=u*10+*c++-48; return u;}int pre[maxn],pos[maxn],cnt;LL f[maxn][2];bool v[maxn],use[maxn],iskeypoint[maxn];typedef pair<LL,int>Pair;void spfa(){ for(int i=1;i<=n;i++) f[i][0]=1e14; f[S][0]=0; priority_queue<Pair,vector<Pair>,greater<Pair> >Q; Q.push(make_pair(0,S)); while(!Q.empty()) { Pair top=Q.top(); Q.pop(); int x=top.second; if(v[x]) continue; for(int i=head[x];i;i=table[i].next) if(f[table[i].to][0]>f[x][0]+table[i].len&&!v[table[i].to]) { pre[table[i].to]=i; f[table[i].to][0]=f[x][0]+table[i].len; Q.push(make_pair(f[table[i].to][0],table[i].to)); } }}int ans[maxn][2],num[maxn];void QWQ(int k){ memset(v,0,sizeof v); for(int i=1;i<=n;i++) f[i][k]=1e14; priority_queue<Pair,vector<Pair>,greater<Pair> >Q; if(k==0) f[S][0]=0,Q.push(make_pair(0,S)); else f[T][1]=0,Q.push(make_pair(0,T)); while(!Q.empty()) { Pair top=Q.top(); Q.pop(); int x=top.second; if(v[x]) continue; for(int i=head[x];i;i=table[i].next) if(f[table[i].to][k]>f[x][k]+table[i].len&&!v[table[i].to]) { if(iskeypoint[table[i].to]&&iskeypoint[x]) ans[table[i].to][k]=i; else ans[table[i].to][k]=ans[x][k]; f[table[i].to][k]=f[x][k]+table[i].len; Q.push(make_pair(f[table[i].to][k],table[i].to)); } }}void maketree(int x,int l,int r){ t[x].l=l; t[x].r=r; t[x].lazy=t[x].s=1e14; if(l==r) return ; int mid=l+r>>1; maketree(x<<1,l,mid); maketree(x<<1|1,mid+1,r); t[x].s=min(t[x<<1].s,t[x<<1|1].s);}void change(int x,int l,int r,LL tar){ if(t[x].l==l&&t[x].r==r) { t[x].lazy=min(t[x].lazy,tar); return ; } int mid=t[x].l+t[x].r>>1; int lc=x<<1,rc=x<<1|1; if(r<=mid) change(x<<1,l,r,tar); else if(l>mid) change(x<<1|1,l,r,tar); else change(x<<1,l,mid,tar),change(x<<1|1,mid+1,r,tar);}LL res;void search(int x,int pos){ res=min(res,t[x].lazy); if(t[x].l==t[x].r) return ; int mid=t[x].l+t[x].r>>1; int lc=x<<1,rc=x<<1|1; if(pos<=mid) return search(x<<1,pos); return search(x<<1|1,pos);}int main(){ scanf("%d%d",&n,&m); int x,y,c; for(int i=1;i<=m;i++) { x=read(); y=read(); c=read(); add(x,y,c); add(y,x,c); } S=read(); T=read(); spfa(); int hh=T; while(hh) { if(pre[hh]) pos[++cnt]=pre[hh]; use[pre[hh]]=1; iskeypoint[hh]=1; table[pre[hh]].o=1; hh=table[pre[hh]].fr; } for(int i=1;i<=cnt;i++) num[i]=pos[i]; for(int i=1;i<=cnt;i++) pos[i]=num[cnt-i+1]; memset(num,0,sizeof num); for(int i=1;i<=cnt;i++) num[pos[i]]=i; for(int i=1;i<=n;i++) ans[i][0]=-1,ans[i][1]=tot+1; QWQ(0); QWQ(1); maketree(1,1,cnt); for(int i=1;i<=tot;i++) if(!use[i]) { int l=ans[table[i].fr][0],r=ans[table[i].to][1]; int pos1,pos2; if(l==-1) pos1=1; else pos1=num[l]+1; if(r==tot+1) pos2=cnt; else pos2=num[r^1]-1; if(pos1<=pos2) change(1,pos1,pos2,table[i].len+f[table[i].fr][0]+f[table[i].to][1]); } Q=read(); while(Q--) { x=read(); y=read(); int pos; if((table[pre[x]].fr==y||table[pre[y]].fr==x)&&iskeypoint[x]&&iskeypoint[y]) { if(table[pre[y]].fr==x) pos=num[pre[y]]; else pos=num[pre[x]]; res=1e14; search(1,pos); if(res>=1e14) puts("Infinity"); else printf("%lld\n",res); } else printf("%lld\n",f[T][0]); } return 0;}
1 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】【蒲公英】【题解】【分块】
- Python
- 奇异值分解(SVD)(2)
- Qt单元测试QTestLib
- mahout之lda(cvb)运用
- 微信小程序_石头剪刀布
- bzoj 2725 [Violet 6]故乡的梦
- CentOS 6.5使用yum快速搭建LAMP环境
- Java:单例模式的七种写法
- House Robber III——Difficulty:Medium
- 31-wait 大战僵尸
- 实例讲解react+react-router+redux
- 访问谷歌网站
- webservice 入门学习(三)
- ABAP调用外部WebService