BZOJ 1880 Sdoi2009 Elaxia的路线 SPFA+拓扑排序

题目大意:给定一张无向图,,求s1到t1与s2到t2的最长公共最短路

以s1 t1 s2 t2为源做4次最短路

如果某条有向边满足s到起始点的距离+边长+终点到t的距离=s到t的最短路 那么这条边就可以在s到t的最短路上

我们把所有既在s1到t1的最短路上也在s2到t2的最短路上的有向边都拎出来

容易证明这个图一定没有环 因此拓扑排序求最长链即可

写完发现过不去样例。。。

因为这题题目描述与题意不符,两个人从不同方向走同一条边也算满足条件。。。

于是我们把s2和t2反转之后再做一遍即可。。。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 1510using namespace std;struct abcd{int to,f,next;}table[M*M<<1];int head[M],_head[M],tot;int n,m,s1,t1,s2,t2,ans;int f1[M],g1[M],f2[M],g2[M];int degree[M];void Add(int head[],int x,int y,int z){table[++tot].to=y;table[tot].f=z;table[tot].next=head[x];head[x]=tot;}void SPFA(int f[],int S){static int q[65540];static bool v[M];static unsigned short r,h;int i;memset(f,0x3f,sizeof(int)*M);f[S]=0;q[++r]=S;while(r!=h){int x=q[++h];v[x]=false;for(i=head[x];i;i=table[i].next)if(f[table[i].to]>f[x]+table[i].f){f[table[i].to]=f[x]+table[i].f;if(!v[table[i].to])v[table[i].to]=true,q[++r]=table[i].to;}}}void Topology_Sort(){static int f[M],q[M];int i,r=0,h=0;memset(f,0,sizeof f);for(i=1;i<=n;i++)if(!degree[i])q[++r]=i;while(r!=h){int x=q[++h];ans=max(ans,f[x]);for(i=_head[x];i;i=table[i].next){f[table[i].to]=max(f[table[i].to],f[x]+table[i].f);if(!–degree[table[i].to])q[++r]=table[i].to;}}}int main(){int i,x,y,z;cin>>n>>m>>s1>>t1>>s2>>t2;for(i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);Add(head,x,y,z);Add(head,y,x,z);}SPFA(f1,s1);SPFA(g1,t1);SPFA(f2,s2);SPFA(g2,t2);for(x=1;x<=n;x++)for(i=head[x];i;i=table[i].next)if( g1[table[i].to]+table[i].f+f1[x]==f1[t1] && g2[table[i].to]+table[i].f+f2[x]==f2[t2] )Add(_head,x,table[i].to,table[i].f),degree[table[i].to]++;Topology_Sort();SPFA(f2,t2);SPFA(g2,s2);memset(_head,0,sizeof _head);for(x=1;x<=n;x++)for(i=head[x];i;i=table[i].next)if( g1[table[i].to]+table[i].f+f1[x]==f1[t1] && g2[table[i].to]+table[i].f+f2[x]==f2[s2] )Add(_head,x,table[i].to,table[i].f),degree[table[i].to]++;Topology_Sort();cout<<ans<<endl;return 0;}

孝敬父母、疼爱孩子、体贴爱人、善待朋友。

BZOJ 1880 Sdoi2009 Elaxia的路线 SPFA+拓扑排序

相关文章:

你感兴趣的文章:

标签云: