1 条题解
-
0

// 最短路图+拓扑排序 Dijkstra 算法 O(MlogN) #include<bits/stdc++.h> #define pii pair<int,int> using namespace std; const int N=1505,M=6e5+5; int idx,h[N],to[M],ww[M],ne[M]; void add(int u,int v,int w){ to[++idx]=v,ww[idx]=w,ne[idx]=h[u],h[u]=idx; } int n,m,s1,t1,s2,t2; int d[4][N]; void dijkstra(int s,int k){ memset(d[k],0x3f,sizeof d[k]); d[k][s]=0; priority_queue<pii,vector<pii>,greater<pii> > q; q.emplace(0,s); while(!q.empty()){ auto [dd,u]=q.top(); q.pop(); if(dd!=d[k][u]) continue; for(int i=h[u];i;i=ne[i]){ int v=to[i],w=ww[i]; if(d[k][v]>d[k][u]+w){ d[k][v]=d[k][u]+w; q.emplace(d[k][v],v); } } } } int on[M],rd[N],f[N],g[N],ans; void topo(){ queue<int> q; q.push(s1); //对甲的DAG图做拓扑排序 while(!q.empty()){ int u=q.front(); q.pop(); ans=max({ans,f[u],g[u]}); for(int i=h[u]; i; i=ne[i])if(on[i]){ //如果边i是甲的DAG中的边 int v=to[i],w=ww[i]; //如果(u,v)也是乙的DAG中的边,那么累计长度 if(d[2][u]+w+d[3][v]==d[2][t2]) f[v]=max(f[v],f[u]+w); //同向走 if(d[3][u]+w+d[2][v]==d[2][t2]) g[v]=max(g[v],g[u]+w); //反向走 if(--rd[v]==0) q.push(v); } } } int main(){ scanf("%d%d%d%d%d%d",&n,&m,&s1,&t1,&s2,&t2); for(int i=1,u,v,w;i<=m;i++) scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w); dijkstra(s1,0),dijkstra(t1,1); dijkstra(s2,2),dijkstra(t2,3); //预处理以4个点为起点的最短路 for(int u=1;u<=n;u++)for(int i=h[u];i;i=ne[i]){ int v=to[i],w=ww[i]; if(d[0][u]+w+d[1][v]==d[0][t1]) on[i]=1,rd[v]++; //标记甲的DAG图上的边和点的入度 } topo(); printf("%d",ans); }
- 1
信息
- ID
- 3545
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 2
- 上传者