SDOI2009 Elaxia的路线(最短路+拓扑排序)
来源:互联网 发布:apache ab工具 编辑:程序博客网 时间:2024/06/13 02:30
题目描述
最近,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,输入数据保证没有重边和自环。
思路
这是一道山东省选题,虽然很容易看出就是一道最短路的题目 但是还是不会做
一开始以为要两次最短路来实现但是写了一下还是写不出来啊…
只好借鉴了一下另一位Dalao的题解了,他的想法如下:
先把以四个点为起点的SPFA跑一遍,然后建新图
只保留Elaxia的最短路(边权为0)和Elaxia、w的公共最短路。
这里怎么判断某边是否是最短路呢?答案是:dis(s,i)+len(i,j)+dis(j,t)=dis(s,t)
下一步可以用拓扑排序递推:f[b[i].t]=max(f[b[i].t],f[temp]+b[i].v*b[i].ok)
最后输出Elaxia终点的f值。
代码(其实还是很好实现的)
#include<queue>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;struct node{ int u,v,w,nxt,f;}a[2000005],b[2000005];queue<int>q;int n,m,cnt,ct2;int h[2005],p[5],d[5][2005],h2[2005],r[2005],f[2005];//这里其实1505就行void add(int u,int v,int w){ a[++cnt].u=u; a[cnt].v=v; a[cnt].w=w; a[cnt].nxt=h[u]; h[u]=cnt;}void SPFA(int x)//就是正常的SPFA{ bool v[1505]={0}; for(int i=1;i<=n;++i) if(i!=p[x]) d[x][i]=0x3f3f3f3f; q.push(p[x]); v[p[x]]=1; while( !q.empty() ) { int now=q.front(); q.pop(),v[now]=0; for(int i=h[now];i;i=a[i].nxt) { int to=a[i].v; if(d[x][to]>d[x][now]+a[i].w) { d[x][to]=d[x][now]+a[i].w; if(!v[to]) v[to]=1,q.push(to); } } }}int main(){ int x,y,z; scanf("%d%d",&n,&m); for(int i=1;i<=4;++i) scanf("%d",&p[i]); for(int i=1;i<=m;++i) { scanf("%d%d%d",&x,&y,&z); add(x,y,z),add(y,x,z); } for(int i=1;i<=4;++i) SPFA(i); for(int i=1;i<=cnt;++i) //以Elaxia为主重建图 if(d[1][a[i].u]+a[i].w+d[2][a[i].v]==d[1][p[2]]) { b[++ct2].u==a[i].u; b[ct2].v=a[i].v; b[ct2].w=a[i].w; b[ct2].nxt=h2[a[i].u]; h2[a[i].u]=ct2; if(d[3][a[i].u]+a[i].w+d[4][a[i].v]==d[3][p[4]]||d[4][a[i].u]+a[i].w+d[3][a[i].v]==d[3][p[4]]) b[ct2].f=1; r[a[i].v]++; } q.push(p[1]); int now; while(!q.empty())//拓扑排序找关键路径 { now=q.front(); q.pop(); for(int i=h2[now];i;i=b[i].nxt) { --r[b[i].v]; if(!r[b[i].v]) { q.push(b[i].v); f[b[i].v]=max(f[b[i].v],f[now]+b[i].w*b[i].f); } } } printf("%d",f[p[2]]); return 0;}
- SDOI2009 Elaxia的路线(最短路+拓扑排序)
- [BZOJ1880][Sdoi2009] Elaxia的路线 (最短路,拓扑排序)
- 洛谷P2149 [SDOI2009]Elaxia的路线(最短路,拓扑排序)
- (bzoj 1880 [Sdoi2009]Elaxia的路线)<最短路+拓扑最长链>
- Elaxia的路线 SDOI2009 最短路
- bzoj 1880: [Sdoi2009]Elaxia的路线(拓扑排序+spfa)
- [BZOJ1880][SDOI2009]Elaxia的路线(SPFA+拓扑排序+DP)
- bzoj 1880: [Sdoi2009]Elaxia的路线 最短路
- BZOJ 1880 Sdoi2009 Elaxia的路线 SPFA+拓扑排序
- BZOJ-1880-Elaxia的路线-SDOI2009-SPFA+拓扑排序
- [SDOI2009]Elaxia的路线
- [SDOI2009]Elaxia的路线
- [BZOJ]1880: [Sdoi2009]Elaxia的路线 spfa+拓扑图DP
- BZOJ1880[Sdoi2009]Elaxia的路线 spfa+拓扑序
- 【SDOI2009】【BZOJ1880】Elaxia的路线
- BZOJ1880: [Sdoi2009]Elaxia的路线
- luogu2149 [SDOI2009]Elaxia的路线
- bzoj1880 [Sdoi2009]Elaxia的路线
- POJ3040
- 首页限时跳转 Handler+SharedPreferences
- C++ MFC / VS2013 之十七(对话框:颜色对话框)
- Error与Exception的区别
- HDOJ 2098 分拆素数和
- SDOI2009 Elaxia的路线(最短路+拓扑排序)
- 大众点评CAT安装部署记录
- Tomcat 9 + Let's encrypt 免费 SSL 升级 https
- c语言操作符
- AsyncTask,在studio中会用到子节流转换字符串
- FM1702 13.56MHz RF PCB天线调试经验记录
- 【叉积性质】POJ 2318 TOYS && POJ 2398 Toy Storage
- 二维码扫描
- 进程间通讯——信号量(一)