BZOJ 1880 [Sdoi2009]Elaxia的路线
来源:互联网 发布:java 防止xss攻击 编辑:程序博客网 时间:2024/06/05 09:57
大家都说这是一道大水题。。。想打dyx
应该了解到拓扑排序的功能,类比于食物链那道题,拓扑排序可以dp求出最长链。而在这道题只需求出可以重复的部分搞一个拓扑排序即可。
而怎样求重复的部分呢?有一个思想很好:将一条线路拆分成起点到此的距离和终点到此的距离,跑两遍单源最短路,然后类似地枚举求出一些可以重复的路径,Topo一下就好了
(尝试新代码风格2333,bz会卡空间,实测将边的数量开小一半就可以过了)
#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<queue>#include<algorithm>using namespace std;const int maxn=1501;struct edge{ int from,to,next,val;}oe[maxn*maxn>>1],nowe[maxn*maxn>>1];int n,ocnt,nowcnt,ans,m,S1,S2,T1,T2;int ohead[maxn],nowhead[maxn],f[maxn],degree[maxn];int dists1[maxn],dists2[maxn],distt1[maxn],distt2[maxn];bool vst[maxn];void insert(int &cnt,int head[],edge e[],int from,int to,int val){ e[++cnt].from=from;e[cnt].to=to;e[cnt].val=val;e[cnt].next=head[from];head[from]=cnt;}void spfa(int S,int head[],edge e[],int dist[]){ queue<int>q; memset(dist+1,0x3f,sizeof(int)*n); memset(vst+1,0,sizeof(bool)*n); q.push(S); vst[S]=true;dist[S]=0; while(!q.empty()) { int u=q.front(); q.pop(); vst[u]=false; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(dist[u]+e[i].val<dist[v]) { dist[v]=dist[u]+e[i].val; if(!vst[v])vst[v]=true,q.push(v); } } }}void Topological_sort(int head[],edge e[]){ memset(f+1,0,sizeof(int)*n); queue<int>q; for(int i=1;i<=n;i++) if(!degree[i])q.push(i); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].next) { int v=e[i].to; f[v]=max(f[v],f[u]+e[i].val); ans=max(ans,f[v]); degree[v]--; if(!degree[v])q.push(v); } }}int main(){ scanf("%d%d",&n,&m); scanf("%d%d%d%d",&S1,&T1,&S2,&T2); for(int i=1,u,v,val;i<=m;i++) { scanf("%d%d%d",&u,&v,&val); insert(ocnt,ohead,oe,u,v,val); insert(ocnt,ohead,oe,v,u,val); } spfa(S1,ohead,oe,dists1); spfa(T1,ohead,oe,distt1); spfa(S2,ohead,oe,dists2); spfa(T2,ohead,oe,distt2); for(int i=1;i<=ocnt;i++) if(dists1[oe[i].from]+oe[i].val+distt1[oe[i].to]==dists1[T1]) if(dists2[oe[i].from]+oe[i].val+distt2[oe[i].to]==dists2[T2]) insert(nowcnt,nowhead,nowe,oe[i].from,oe[i].to,oe[i].val),degree[oe[i].to]++; Topological_sort(nowhead,nowe); memset(nowhead+1,0,sizeof(int)*n); memset(degree+1,0,sizeof(int)*n); nowcnt=0; for(int i=1;i<=ocnt;i++) if(dists1[oe[i].from]+oe[i].val+distt1[oe[i].to]==dists1[T1]) if(distt2[oe[i].from]+oe[i].val+dists2[oe[i].to]==distt2[S2]) insert(nowcnt,nowhead,nowe,oe[i].from,oe[i].to,oe[i].val),degree[oe[i].to]++; Topological_sort(nowhead,nowe); cout<<ans; return 0;}
阅读全文
0 0
- 【bzoj 1880】: [Sdoi2009]Elaxia的路线
- 【BZOJ 1880】 [Sdoi2009]Elaxia的路线
- 【39.87%】【BZOJ 1880】[Sdoi2009]Elaxia的路线
- BZOJ 1880 [Sdoi2009]Elaxia的路线
- 1880: [Sdoi2009]Elaxia的路线
- BZOJ 1880 Sdoi2009 Elaxia的路线 SPFA+拓扑排序
- BZOJ-1880-Elaxia的路线-SDOI2009-SPFA+拓扑排序
- bzoj 1880: [Sdoi2009]Elaxia的路线(拓扑排序+spfa)
- bzoj 1880: [Sdoi2009]Elaxia的路线 最短路
- [BZOJ]1880: [Sdoi2009]Elaxia的路线 spfa+拓扑图DP
- 【BZOJ】【P1880】【Sdoi2009】【Elaxia的路线】【dijk】
- [SDOI2009]Elaxia的路线
- [SDOI2009]Elaxia的路线
- 【BZOJ 1880】 Elaxia的路线
- 【SDOI2009】【BZOJ1880】Elaxia的路线
- BZOJ1880: [Sdoi2009]Elaxia的路线
- luogu2149 [SDOI2009]Elaxia的路线
- bzoj1880 [Sdoi2009]Elaxia的路线
- 【二分+最小生成树】BZOJ2654[tree]题解
- 开源大数据周刊-第70期
- 【NOIP考前题目回顾】Luogu P1040
- 求数组元素的和
- ucos ii 文件分析
- BZOJ 1880 [Sdoi2009]Elaxia的路线
- C学习笔记--fputc()与fgetc()
- 扫雷游戏
- freemarker 使用记录
- web.xml 文件配置 标签解释
- 【编译原理】语法分析(一)
- 求值
- AJAX的初级使用及登录注册案例
- OkHttp的基本使用——替代Apache HttpClient