[SDOI2009]Elaxia的路线
Posted hjmmm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI2009]Elaxia的路线相关的知识,希望对你有一定的参考价值。
求无向图中,两对点间最短路的最长公共路径
喵啊…这题真心喵啊…orzorz
先spfa求出x1, y1, x2, y2的单源最短路
然后把x1到y1的最短路们建图
判断方式(精髓!):
if(dis[0][uu] + ww + dis[1][vv] == dis[0][y1]){ addedge(uu, vv, ww, 1); ind[vv]++; }
蒟蒻欲膜又止【划掉
注意 建完是有向图哦
在建完图之后 用同样的方式判断这个新图上有哪些边在x2-y2的最短路上 并标记
注意这里有个坑点 就是这两位小彩虹不一定要并肩走的…他们满足于相互呼唤… (* ̄︶ ̄* )
所以要判断一下正向和反向 只要有一个满足这条边就可以标记
那这里一段,那里一段怎么统计呢?
其实 同一条x2-y2最短路在新图上是连续的 因为如果中间有更短的地方 他们两个为什么不一起走另一条路呢?
所以最后按拓扑序bfs就好了
另 咱们能拓扑就别dfs 分分钟T爆……
1 int main(){ 2 init(); 3 spfa(x1, 0); 4 spfa(y1, 1); 5 spfa(x2, 2); 6 spfa(y2, 3); 7 int tmp = esize[0]; 8 for(int i = 1; i <= tmp; i++){ 9 int vv = edge[0][i].v, uu = edge[0][i].u, ww = edge[0][i].w; 10 if(dis[0][uu] + ww + dis[1][vv] == dis[0][y1]){ 11 addedge(uu, vv, ww, 1); 12 ind[vv]++; 13 } 14 } 15 tmp = esize[1]; 16 for(int i = 1; i <= tmp; i++){ 17 int vv = edge[1][i].v, uu = edge[1][i].u, ww = edge[1][i].w; 18 if(dis[2][uu] + ww + dis[3][vv] == dis[2][y2] || dis[2][vv] + ww + dis[3][uu] == dis[2][y2]) 19 flag[i] = 1; 20 } 21 bfs(); 22 printf("%d", f[y1]); 23 return 0; 24 }
1 inline void bfs(){ 2 q.push(x1); 3 while(!q.empty()){ 4 int fro = q.front(); q.pop(); 5 for(int i = head[1][fro]; i != -1; i = edge[1][i].next){ 6 int vv = edge[1][i].v, ww = edge[1][i].w; 7 f[vv] = max(f[vv], f[fro] + flag[i] * ww); 8 ind[vv]--; 9 if(!ind[vv]) q.push(vv); 10 } 11 } 12 }
1 inline void spfa(int s, int tp){ 2 q.push(s); 3 dis[tp][s] = 0; 4 for(int i = 1; i <= n; i++) vis[i] = 0; 5 while(!q.empty()){ 6 int fro = q.front(); q.pop(); vis[fro] = 0; 7 for(int i = head[0][fro]; i != -1; i = edge[0][i].next){ 8 int vv = edge[0][i].v, ww = edge[0][i].w; 9 if(dis[tp][vv] > dis[tp][fro] + ww){ 10 dis[tp][vv] = dis[tp][fro] + ww; 11 if(!vis[vv]){ 12 q.push(vv); 13 vis[vv] = 1; 14 } 15 } 16 } 17 } 18 }
以上是关于[SDOI2009]Elaxia的路线的主要内容,如果未能解决你的问题,请参考以下文章