BZOJ1880: [Sdoi2009]Elaxia的路线
Posted Izaya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1880: [Sdoi2009]Elaxia的路线相关的知识,希望对你有一定的参考价值。
题意:求最短路最长公共距离。
考虑每一条边,如果满足dis(s1,u)+len+dis(v,t1)==dis(s1,t1) && dis(s2,u)+len+dis(v,t2)==dis(s2,t2) 则该边在公共最短路上
拓扑排序dp下即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1505 4 #define INF 1e9 5 int n,m,a[5],dis[5][N],cnt,cnt1,head[N],head1[N],r[N],ans[N],fin; 6 bool y[N]; 7 struct data{ 8 int num,v; 9 bool operator < (const data& w)const{ 10 return v>w.v; 11 } 12 }; 13 priority_queue<data>q; 14 inline int read(){ 15 int x=0,f=1; char a=getchar(); 16 while(a<‘0‘ || a>‘9‘) {if(a==‘-‘) f=-1; a=getchar();} 17 while(a>=‘0‘ && a<=‘9‘) x=x*10+a-‘0‘,a=getchar(); 18 return x*f; 19 } 20 struct edges{ 21 int fr,to,v,next; 22 }e[500005],e1[500005]; 23 void inser(int u,int v,int c){ 24 e[cnt]=(edges){u,v,c,head[u]};head[u]=cnt++; 25 e[cnt]=(edges){v,u,c,head[v]};head[v]=cnt++; 26 } 27 void ins(int u,int v,int c){ 28 if(dis[1][u]>dis[1][v]) swap(u,v); 29 e1[cnt1]=(edges){u,v,c,head1[u]};head1[u]=cnt1++; r[v]++; 30 } 31 void dj(int x){ 32 dis[x][a[x]]=0; memset(y,0,sizeof(y));q.push((data){a[x],0}); 33 int s,to; 34 while(!q.empty()){ 35 s=q.top().num; q.pop(); 36 if(y[s]) continue; y[s]=1; 37 for(int i=head[s];i>=0;i=e[i].next){ 38 if(y[e[i].to]) continue; to=e[i].to; 39 if(dis[x][to]>dis[x][s]+e[i].v) dis[x][to]=dis[x][s]+e[i].v,q.push((data){to,dis[x][to]}); 40 } 41 } 42 } 43 void topsort(int x){ 44 r[x]--; 45 for(int i=head1[x];i>=0;i=e1[i].next){ 46 ans[e1[i].to]=max(ans[e1[i].to],ans[x]+e1[i].v); 47 fin=max(ans[e1[i].to],fin); 48 r[e1[i].to]--; if(!r[e1[i].to]) topsort(e1[i].to); 49 } 50 } 51 int main(){ 52 n=read(); m=read(); 53 memset(dis,34,sizeof(dis)); 54 memset(head,-1,sizeof(head)); 55 memset(head1,-1,sizeof(head1)); 56 for(int i=1;i<=4;i++) a[i]=read(); 57 for(int u,v,c,i=1;i<=m;i++) 58 u=read(),v=read(),c=read(),inser(u,v,c); 59 for(int i=1;i<=4;i++) dj(i); 60 for(int i=0;i<cnt;i+=2){ 61 int u=e[i].fr,v=e[i].to; 62 if((dis[1][u]+e[i].v+dis[2][v]==dis[1][a[2]] || dis[1][v]+e[i].v+dis[2][u]==dis[1][a[2]]) && (dis[3][u]+e[i].v+dis[4][v]==dis[3][a[4]] || dis[3][v]+e[i].v+dis[4][u]==dis[3][a[4]])) 63 ins(u,v,e[i].v); 64 } 65 for(int i=1;i<=n;i++) 66 if(!r[i]) topsort(i); 67 printf("%d\n",fin); 68 return 0; 69 }
以上是关于BZOJ1880: [Sdoi2009]Elaxia的路线的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1880 [Sdoi2009]Elaxia的路线(最短路+拓扑序)
bzoj 1880: [Sdoi2009]Elaxia的路线spfa+拓扑排序
BZOJ1880 SDOI2009 Elaxia的路线 最短路+拓扑排序