JZOJ3773【NOI模拟】小 P 的烦恼(拓扑排序,贪心,找桥)
来源:互联网 发布:nginx module 编辑:程序博客网 时间:2024/05/21 16:21
Description
小 P 最近遇上了大麻烦,他的高等代数挂科了。于是他只好找高代老师求情。善良的高代老师答应不挂他,但是要求小 P 帮助他一起解决一个难题。
问题是这样的,高代老师近期要组织班上同学一起去漂流,漂流可以看做是在一张 n 个点 m 条边的有向无环图上进行的,点编号从 0 到 n-1 ,表示景点; 边是连接各景点的一定长度的河道。同时,定义编号为 s 是起点而 t 是终点。我们不妨把从 s 点到 t 点不论走什么样的路径都需要经过的边称为桥, 这些桥由于地势险要所以是危险的。现在高代老师有两条长度为 l 的安全绳,他希望用这两条安全绳覆盖尽可能长的桥,使得他们通过的桥的长度之和尽量短。
Solution
首先这题最重要的问题就是找桥边,那么我们有一个很方便的方法,因为是DAG,所以我们可以对于一条边i–j,如果S到i的方案数*j到T的方案数=S到T的方案数,那么这条边就是桥边。
求方案数,正着连边拓扑一下,反着连边拓扑一下。注意方案数模上一个大质数,如果怕错可以搞两个质数。
然后把S-T上的路径提出来,先求一个p[i]和q[i]表示从i开始向左向右长度为L能覆盖的桥的长度,然后把他们前缀后缀max一下,枚举i,p[i]和q[i+1]合并。
我们还要考虑两个桥合并的情况,那么就相当于用2*L的长度来覆盖,和上面求p、q的方法一样。
Code
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)#define rep(i,a) for(i=first[a];i;i=next[i])#define rep1(i,a) for(i=first1[a];i;i=next1[i])using namespace std;typedef long long ll;const int maxn=2e5+7,mo=1e9+7;ll i,j,k,l,t,n,m,ans,T,S,cas,x,y,z,L,u,r,ans1,oo;ll first[maxn],last[maxn],next[maxn],chang[maxn],num;ll first1[maxn],last1[maxn],next1[maxn],chang1[maxn],num1;ll d[maxn*50],c[maxn],cc[maxn],head,tail,g[maxn],tot,p[maxn],q[maxn];ll f[maxn],f1[maxn];bool bz[maxn],az,cz[maxn];struct node{ ll a,b,c;}e[maxn];void add(ll x,ll y,ll z){ last[++num]=y,next[num]=first[x],first[x]=num;chang[num]=z; last1[++num1]=x,next1[num1]=first1[y],first1[y]=num1;chang1[num1]=z;}void spfa(){ ll i,j,x; memset(bz,0,sizeof(bz));head=0; memset(g,127/3,sizeof(g));g[d[tail=1]=S]=0;bz[S]=1;oo=g[0]; while(head<tail){ x=d[++head]; rep(i,x){ if(g[x]+chang[i]<g[last[i]]){ g[last[i]]=g[x]+chang[i]; if(!bz[last[i]])bz[last[i]]=1,d[++tail]=last[i]; } } bz[x]=0; }}void dfs(int x,int y){ if(x==T){az=1;return;} int i; rep(i,x){ if(last[i]!=y&&g[last[i]]-chang[i]==g[x]){ dfs(last[i],x); if(az){ e[++tot].a=g[last[i]];e[tot].b=chang[i]; e[tot].c=0;if(cz[i]){ e[tot].c=1,ans1+=chang[i]; } return; } } }}bool cmp(node x,node y){return x.a<y.a;}int main(){ // freopen("fan.in","r",stdin); for(scanf("%lld",&cas);cas;cas--){ scanf("%lld%lld%lld%lld%lld",&n,&m,&S,&T,&L);S++,T++; num=num1=0;memset(first,0,sizeof(first));ans=ans1=0; memset(first1,0,sizeof(first1)); memset(c,0,sizeof(c));memset(cc,0,sizeof(cc)); memset(f,0,sizeof(f));memset(f1,0,sizeof(f1)); fo(i,1,m){ scanf("%lld%lld%lld",&x,&y,&z);x++,y++; add(x,y,z); c[y]++;cc[x]++; } head=tail=0;d[++tail]=S;f[S]=1; while(head<tail){ rep(i,d[++head]){ c[last[i]]--;(f[last[i]]+=f[d[head]])%=mo; if(!c[last[i]])d[++tail]=last[i]; } } head=tail=0;d[++tail]=T;f1[T]=1; while(head<tail){ rep1(i,d[++head]){ cc[last1[i]]--;(f1[last1[i]]+=f1[d[head]])%=mo; if(!cc[last1[i]])d[++tail]=last1[i]; } } spfa();tot=0; if(g[T]==oo){ printf("-1\n"); continue; } memset(cz,0,sizeof(cz)); fo(i,1,n)rep(j,i)if(f[i]*f1[last[j]]%mo==f[T])cz[j]=1; az=0;dfs(S,0); sort(e+1,e+1+tot,cmp);e[tot+1]=(node){0,0,0}; memset(p,0,sizeof(p));memset(q,0,sizeof(q)); l=1;r=0;t=0;u=0; fo(i,1,tot){ t+=e[i].b,u+=e[i].c*e[i].b; while(l<=i&&t>L)t-=e[l].b,u-=e[l].c*e[l].b,l++; q[i]=u;if(e[l-1].c)q[i]+=L-t; } l=1;t=u=0; fo(i,1,tot){ t+=e[i].b,u+=e[i].c*e[i].b; while(l<=i&&t>L*2)t-=e[l].b,u-=e[l].c*e[l].b,l++; if(e[l-1].c)ans=max(ans,u+L*2-t);else ans=max(ans,u); } r=tot;t=0;u=0; fod(i,tot,1){ t+=e[i].b,u+=e[i].c*e[i].b; while(r>=i&&t>L)t-=e[r].b,u-=e[r].c*e[r].b,r--; p[i]=u;if(e[r+1].c)p[i]+=L-t; } fo(i,1,tot)q[i]=max(q[i],q[i-1]);fod(i,tot,1)p[i]=max(p[i+1],p[i]); fo(i,1,tot)ans=max(q[i-1]+p[i],ans); printf("%lld\n",ans1-ans); }}
阅读全文
1 0
- JZOJ3773【NOI模拟】小 P 的烦恼(拓扑排序,贪心,找桥)
- 【jzoj3773】【NOI2015模拟8.15】【小 P 的烦恼】【动态规划】
- 【JZOJ3773】【NOI2015模拟8.15】小 P 的烦恼
- NYOJ-453 小珂的烦恼【模拟||找规律】
- 8.12NOI(P)模拟
- [NOIP模拟][拓扑排序][贪心]拆网线
- 【JZOJ 3773】 小 P 的烦恼
- 2014.8.12 Noi(p)模拟
- [NOI(P?)2017模拟]围城
- [NOI(P?)2017模拟]字符串
- 1660:小邪的烦恼(贪心)
- NYOJ 453 小珂的烦恼 模拟
- ZOJ 3780Paint the Grid Again-贪心模拟/拓扑排序
- bzoj 3281: 小P的烦恼 支配树算法+dp
- hunnu11544:小明的烦恼——找字符串
- hunnu--11545--小明的烦恼——找路径
- 【NOI(P)2013模拟】秘密任务
- POJ3687拓扑排序+贪心
- 输入外挂
- 此题请去QDU找帅气的HYC与露珠
- 【03】前端面试题
- 网易调整队形(动态规划)
- yum [Errno 14] problem making ssl connection CentOs
- JZOJ3773【NOI模拟】小 P 的烦恼(拓扑排序,贪心,找桥)
- KMP
- java native 关键字
- iOS蓝牙开发 Bluetooth蓝牙CoreBluetooth 蓝牙中心设备的实现 蓝牙外设的实现 有Demo
- 测试博客链接
- 文章标题 HRBUST 1400 : 汽车比赛(树状数组 )
- hdu1081
- 腾讯art-template4,即vue后又获一利器
- Apache启动时报错Could not reliably determine the server's fully qualified domain name