[SDOI2009]Elaxia的路线
来源:互联网 发布:云南大学urp软件下载 编辑:程序博客网 时间:2024/05/16 04:37
最近,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。
输出格式:
一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)
最短路上求最长公共路径长,我们的想法是求出两个人的最短路上的边,找重叠部分最长的。
如何判断这条边是否在最短路上呢?正反跑最短路,加上那条边如果距离最短,就是最短路上的边。(和NOIP2017Park很像)。
最后我们按照一个人的最短路重构图,如果那条边是重叠部分则打上标记。
最短路显然是个DAG(同Park)。所以我们可以拓扑排序DP求出答案。
最后,千万记得!edge别开小了啊。。。。数据范围N是1500,无向完全图有2248500条边啊。。
cjr 是毒瘤出题人;mthq精通数据结构;pkl 是最强女选手;wyj才初三啊;ms默默AK;我没有学上:我们都有光明的前途。
#include<bits/stdc++.h>using namespace std;const int MAXN=5e3+5;const int N=3e6+5;struct edge{ int to,next,w; bool gg;}e[N],e2[N];int head[MAXN],cnt=0,num=0,rehead[MAXN];inline void add(int u,int v,int w){e[++cnt]=(edge){v,head[u],w},head[u]=cnt;}inline void addedge(int u,int v,int w,bool ok){e2[++num]=(edge){v,rehead[u],w,ok},rehead[u]=num;}int n,m,x,y,xx,yy,di=0;int dis[MAXN][4];// 0 正 1反 2 正 3反 bool vis[MAXN];int inde[MAXN],rk[MAXN],f[MAXN];queue<int>q;void SPFA(int x,int times){ q.push(x);vis[x]=1;dis[x][times]=0; while(q.size()){ int u=q.front();q.pop(); vis[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].to,w=e[i].w; if(dis[u][times]+w<dis[v][times]){ dis[v][times]=dis[u][times]+w; if(!vis[v]){ vis[v]=1;q.push(v); } } } }}void readd(int base){ for(int u=1;u<=n;u++){ for(int i=head[u];i;i=e[i].next){ int v=e[i].to,w=e[i].w; if(dis[u][0]+w+dis[v][1]==dis[y][0]){//要按照一个图的顺序来重建图,不然会不知道方向 inde[v]++; if(dis[u][2]+w+dis[v][3]==dis[yy][2]||dis[v][2]+w+dis[u][3]==dis[xx][3])addedge(u,v,w,1);//只要有一个满足就是公共的 //因为题里迎面走来也是可以的 else addedge(u,v,w,0); } } }}void topsort(){ q.push(x); while(q.size()){ int u=q.front();q.pop(); rk[++di]=u; for(int i=rehead[u];i;i=e2[i].next){ int v=e2[i].to,w=e2[i].w,l=e2[i].gg; inde[v]--; if(!inde[v]){ q.push(v); } // f[v]=max(f[v],f[u]+w*l);在这里DP也可以(因为是按照拓扑序的) } }}int dp(){ for(int i=1;i<=di;i++){ int u=rk[i]; for(int j=rehead[u];j;j=e2[j].next){ int v=e2[j].to,w=e2[j].w,l=e2[j].gg; f[v]=max(f[v],f[u]+w*l); } } return f[y];}int main(){ memset(dis,0x7f,sizeof(dis)); int tem1,tem2,tem3; scanf("%d%d",&n,&m); scanf("%d%d%d%d",&x,&y,&xx,&yy); for(int i=1;i<=m;i++){ scanf("%d%d%d",&tem1,&tem2,&tem3); add(tem1,tem2,tem3); add(tem2,tem1,tem3); } SPFA(x,0);SPFA(y,1);SPFA(xx,2);SPFA(yy,3); readd(0);topsort(); printf("%d\n",dp()); return 0;}
附一篇写的非常棒的洛谷题解(最后一篇)
- [SDOI2009]Elaxia的路线
- [SDOI2009]Elaxia的路线
- 【SDOI2009】【BZOJ1880】Elaxia的路线
- BZOJ1880: [Sdoi2009]Elaxia的路线
- luogu2149 [SDOI2009]Elaxia的路线
- bzoj1880 [Sdoi2009]Elaxia的路线
- 1880: [Sdoi2009]Elaxia的路线
- bzoj1880: [Sdoi2009]Elaxia的路线
- bzoj1880: [Sdoi2009]Elaxia的路线
- 【BZOJ1880】【SDOI2009】Elaxia的路线
- bzoj1880: [Sdoi2009]Elaxia的路线 wikioi2309 SPFA
- 【BZOJ】【P1880】【Sdoi2009】【Elaxia的路线】【dijk】
- 【bzoj 1880】: [Sdoi2009]Elaxia的路线
- 【BZOJ 1880】 [Sdoi2009]Elaxia的路线
- BZOJ1880: [Sdoi2009]Elaxia的路线|dijksrtra|暴力
- 【39.87%】【BZOJ 1880】[Sdoi2009]Elaxia的路线
- 洛谷 P2149 [SDOI2009] Elaxia的路线
- Elaxia的路线 SDOI2009 最短路
- IO多路复用之epoll总结
- Linux进程状态总结
- 使用ScheduledThreadPoolExecutor 替代 Timer
- 以Point类为基础,定义一个平面中的Circle类
- 复杂网络简单理解
- [SDOI2009]Elaxia的路线
- SVN,工作副本锁定的解决方法
- MyRapid Winform 快速开发框架
- Python搜索引擎实现原理和方法
- 百度AI结构化数据提取
- css
- 关于Springboot整合mybatis启动的问题
- 工具类总结(1)-Struts2ScopeUtil
- Masscan工具使用