[SDOI2009]Elaxia的路线 SPFA+Topo

P2149 [SDOI2009]Elaxia的路线

题目描述

最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

输入输出格式

输入格式:

第一行:两个整数N和M(含义如题目描述)。 第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。 接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。

输出格式:

一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

输入输出样例

输入样例#1:

9 10
1 6 7 8
1 2 1
2 5 2
2 3 3
3 4 2
3 9 5
4 5 3
4 6 4
4 7 2
5 8 1
7 9 1

输出样例#1:

3

说明

对于30%的数据,N <= 100;

对于60%的数据,N <= 1000;

对于100%的数据,N <= 1500,输入数据保证没有重边和自环。

从 四个点 分别跑一次SPFA 记录dis值

然后找出重复路径 跑Topo 排序 找重复路径的最大值

不过由于路径的方向问题 有可能有重复的路径无法被记录

只需要把 x2 y2 倒过来跑一遍就好了

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cctype>
  4 #include <vector>
  5
  6 const int MAXN=2010;
  7 const int INF=0x7fffffff;
  8
  9 int n,m,x1,y1,x2,y2,ans;
 10
 11 int dis[6][MAXN],num[MAXN],in[MAXN],q[MAXN*1000];
 12
 13 bool vis[MAXN];
 14
 15 inline void read(int&x) {
 16     int f=1;register char c=getchar();
 17     for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar());
 18     for(;isdigit(c);x=x*10+c-48,c=getchar());
 19     x=x*f;
 20 }
 21
 22 struct node {
 23     int to,val;
 24     node() {}
 25     node(int to,int val):to(to),val(val) {}
 26 };
 27
 28 std::vector<node> Graph[MAXN],New[MAXN];
 29
 30 void SPFA(int S,int flag) {
 31     for(register int i=1;i<=n;++i) dis[flag][i]=INF,vis[i]=false;
 32     dis[flag][S]=0;
 33     std::queue<int> Q;
 34     Q.push(S);
 35     while(!Q.empty()) {
 36         int u=Q.front();
 37         Q.pop();
 38         vis[u]=false;
 39         for(register int i=0;i<Graph[u].size();++i) {
 40             node p=Graph[u][i];
 41             if(dis[flag][p.to]>dis[flag][u]+p.val) {
 42                 dis[flag][p.to]=dis[flag][u]+p.val;
 43                 if(!vis[p.to]) Q.push(p.to),vis[p.to]=true;
 44             }
 45         }
 46     }
 47 }
 48
 49 void topo() {
 50     int head=0,tail=0;
 51     for(int i=1;i<=n;++i) {
 52         if(!in[i]) q[++tail]=i;
 53         dis[5][i]=0;
 54     }
 55     while(head<tail) {
 56         int u=q[++head];
 57         for(int i=0;i<New[u].size();++i) {
 58             node v=New[u][i];
 59             dis[5][v.to]=dis[5][u]+v.val;
 60             if(!--in[v.to]) q[++tail]=v.to;
 61         }
 62     }
 63     for(int i=1;i<=n;++i)
 64       ans=ans<dis[5][i]?dis[5][i]:ans;
 65     return;
 66 }
 67
 68 int hh() {
 69     read(n);read(m);
 70     read(x1);read(y1);read(x2);read(y2);
 71     for(register int x,y,z,i=1;i<=m;++i) {
 72         read(x);read(y);read(z);
 73         Graph[x].push_back(node(y,z));
 74         Graph[y].push_back(node(x,z));
 75     }
 76     SPFA(x1,1);
 77     SPFA(x2,2);
 78     SPFA(y1,3);
 79     SPFA(y2,4);
 80     for(int i=1;i<=n;++i)
 81       for(int j=0;j<Graph[i].size();++j) {
 82           node v=Graph[i][j];
 83           if(dis[1][i]+dis[3][v.to]+v.val==dis[1][y1]&&dis[2][i]+dis[4][v.to]+v.val==dis[2][y2])
 84             New[i].push_back(node(v.to,v.val)),++in[v.to];
 85       }
 86     topo();
 87     SPFA(y2,2);SPFA(x2,4);
 88     for(int i=1;i<=n;++i) New[i].clear(),in[i]=0;
 89     for(int i=1;i<=n;++i)
 90       for(int j=0;j<Graph[i].size();++j) {
 91           node v=Graph[i][j];
 92           if(dis[1][i]+dis[3][v.to]+v.val==dis[1][y1]&&dis[2][i]+dis[4][v.to]+v.val==dis[2][x2])
 93             New[i].push_back(node(v.to,v.val)),++in[v.to];
 94       }
 95     topo();
 96     printf("%d\n",ans);
 97     return 0;
 98 }
 99
100 int sb=hh();
101 int main(int argc,char**argv) {;}

代码

时间: 2024-08-06 15:11:46

[SDOI2009]Elaxia的路线 SPFA+Topo的相关文章

[BZOJ1880] [Sdoi2009] Elaxia的路线 (SPFA &amp; 拓扑排序)

Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间. 具体地说,就是要求无向图中,两对点间最短路的最长公共路径. Input 第一行:两个整数N和M(含义如题目描述).

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反转之后再做一遍即可... #i

bzoj 1880: [Sdoi2009]Elaxia的路线(拓扑排序+spfa)

1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 974  Solved: 382 [Submit][Status][Discuss] Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是

bzoj1880: [Sdoi2009]Elaxia的路线

1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1035  Solved: 412[Submit][Status][Discuss] Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是E

洛谷——P2149 [SDOI2009]Elaxia的路线

P2149 [SDOI2009]Elaxia的路线 题目描述 最近,Elaxia和w的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间. 具体地说,就是要求无向图中,两对点间最短路的最长公共路径. 输入输出格式 输入格式:

【BZOJ 1880】 [Sdoi2009]Elaxia的路线

1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 660  Solved: 242 [Submit][Status][Discuss] Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间.Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长. 现在已知的是

[SDOI2009]Elaxia的路线

P2149 [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]++; } 蒟蒻欲膜又止[划掉 注意 建完是有向图哦 在建完图之后 用同样的方式判断这个新图上有哪些边在

BZOJ 1880: [Sdoi2009]Elaxia的路线( 最短路 + dp )

找出同时在他们最短路上的边(dijkstra + dfs), 组成新图, 新图DAG的最长路就是答案...因为两人走同一条路但是不同方向也可以, 所以要把一种一个的s,t换一下再更新一次答案 -------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #incl

bzoj 1880: [Sdoi2009]Elaxia的路线【spfa+拓扑排序】

有趣啊 先spfa分别求出以s1,t1,s2,t2为起点的最短路,然后把在s1-->t1或者s2-->t2最短路上的边重新建有向图,跑拓扑最长路即可 #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> using namespace std; const int N=1505,inf=1e9; int n,m,x1