【jzoj3773】【NOI2015模拟8.15】【小 P 的烦恼】【动态规划】
来源:互联网 发布:vr unity3d 比ue4清晰 编辑:程序博客网 时间:2024/05/18 03:23
题目大意
小 P 最近遇上了大麻烦,他的高等代数挂科了。于是他只好找高代老师求情。善良的高代老师答应不挂他,但是要求小 P 帮助他一起解决一个难题。
问题是这样的,高代老师近期要组织班上同学一起去漂流,漂流可以看做是在一张 n 个点 m 条边的有向无环图上进行的,点编号从 0 到 n-1 ,表示景点; 边是连接各景点的一定长度的河道。同时,定义编号为 s 是起点而 t 是终点。我们不妨把从 s 点到 t 点不论走什么样的路径都需要经过的边称为桥, 这些桥由于地势险要所以是危险的。现在高代老师有两条长度为 l 的安全绳,他希望用这两条安全绳覆盖尽可能长的桥,使得他们通过的桥的长度之和尽量短。
解题思路
先拓扑排序,求出每个点到t的dis,每个点到s,到t路径数f,g并取模,可以发现一条边u->v是桥当且仅当f[u]*g[v]==f[t]。找出的桥边一定在s到t的路径上,对dis排序并将相连的桥边合并在一起进行dp。
设f[i][0,1,2]表示处理到第i段桥使用了j条绳的桥的最短长度,转移使用二分求出最多能覆盖到哪里并转移,注意可以两条绳连在一起用。
code
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define LF double#define LL long long#define ULL unsigned LL#define fo(i,j,k) for(LL i=j;i<=k;i++)#define fd(i,j,k) for(LL i=j;i>=k;i--)#define fr(i,j) for(LL i=begin[j];i;i=next[i])using namespace std;LL const mn=1e5+9,mm=2*1e5+9,mo=1e9+7,inf=1e18+7;LL T,n,m,s,t,L,gra,begin[mn],u[mm],v[mm],w[mm],to[mm],len[mm],next[mm],dis[mn],du[mn],q[mn],f[mn],g[mn],F[mn][3],S[mn];LL max(LL x,LL y){return (x>y)?x:y;}LL min(LL x,LL y){return (x<y)?x:y;}void insert(LL u,LL v,LL w){ to[++gra]=v; len[gra]=w; next[gra]=begin[u]; begin[u]=gra;}struct rec{ LL u,v;};rec a[mm];bool cmp(rec x,rec y){ return dis[x.u]>dis[y.u];}int main(){ freopen("d.in","r",stdin); freopen("d.out","w",stdout); scanf("%lld",&T); fo(cas,1,T){ scanf("%lld%lld%lld%lld%lld",&n,&m,&s,&t,&L);s++;t++; gra=0; fo(i,1,n)begin[i]=du[i]=0; fo(i,1,m){ scanf("%lld%lld%lld",&u[i],&v[i],&w[i]);u[i]++;v[i]++; insert(u[i],v[i],w[i]); du[v[i]]++; } LL ti=0; fo(i,1,n)if(!du[i])q[++ti]=i; fo(i,1,n){ LL p=q[i]; fr(j,p){ du[to[j]]--; if(!du[to[j]])q[++ti]=to[j]; } } fo(i,1,n)dis[i]=inf; dis[t]=0; fd(i,n,1){ LL p=q[i]; fr(j,p)dis[p]=min(dis[p],dis[to[j]]+len[j]); } fo(i,1,n)f[i]=g[i]=0; f[s]=1; fo(i,1,n){ LL p=q[i]; fr(j,p)f[to[j]]=(f[to[j]]+f[p])%mo; } g[t]=1; fd(i,n,1){ LL p=q[i]; fr(j,p)g[p]=(g[p]+g[to[j]])%mo; } LL tmp=0; fo(i,1,m)if(f[t]==f[u[i]]*g[v[i]]%mo) a[++tmp].u=u[i],a[tmp].v=v[i]; sort(a+1,a+tmp+1,cmp); LL tm2=0; fo(i,1,tmp)if(a[i].u!=a[i-1].v){ a[++tm2].u=a[i].u; a[tm2].v=a[i].v; }else a[tm2].v=a[i].v; tmp=tm2; fo(i,1,tmp){ S[i]=dis[a[i].u]-dis[a[i].v]; fo(j,0,2){ F[i][j]=F[i-1][j]+S[i]; if(j){ LL l=1,r=i; while(l!=r){ LL md=(l+r+1)/2; if(dis[a[md].u]-dis[a[i].v]<L)r=md-1; else l=md; } F[i][j]=min(F[i][j],F[l-1][j-1]+max(min(dis[a[l].u]-dis[a[i].v]-L,S[l]),0)); if(l+1<=i)F[i][j]=min(F[i][j],F[l][j-1]); if(j==2){ LL l=1,r=i; while(l!=r){ LL md=(l+r+1)/2; if(dis[a[md].u]-dis[a[i].v]<L*2)r=md-1; else l=md; } F[i][j]=min(F[i][j],F[l-1][j-2]+max(min(dis[a[l].u]-dis[a[i].v]-L*2,S[l]),0)); if(l+1<=i)F[i][j]=min(F[i][j],F[l][j-2]); } } } } LL ans=inf; fo(i,0,2)ans=min(ans,F[tmp][i]); if(f[t])printf("%lld\n",ans); else printf("-1\n"); } return 0;}
阅读全文
0 0
- 【jzoj3773】【NOI2015模拟8.15】【小 P 的烦恼】【动态规划】
- 【JZOJ3773】【NOI2015模拟8.15】小 P 的烦恼
- JZOJ3773【NOI模拟】小 P 的烦恼(拓扑排序,贪心,找桥)
- 【JZOJ3771】【NOI2015模拟8.15】小 Z 的烦恼
- 【jzoj3771】【NOI2015模拟8.15】【小 Z 的烦恼】
- 【动态规划】Tom的烦恼
- 【BZOJ3437】小P的牧场 斜率优化 动态规划
- 【JZOJ 3773】 小 P 的烦恼
- NYOJ 453 小珂的烦恼 模拟
- bzoj 3281: 小P的烦恼 支配树算法+dp
- 小P的故事——神奇的Dota (动态规划)
- 动态规划之01背包—小P寻宝记——粗心的基友
- 【动态规划24】bzoj3437小P的牧场(dp+斜率优化)
- [NOI2015]寿司晚宴(状态压缩动态规划)
- 动态规划 problem P
- 蓝桥杯 未名湖边的烦恼 动态规划
- 算法训练 未名湖边的烦恼 (动态规划)
- NYOJ-453 小珂的烦恼【模拟||找规律】
- 初始化脚本脚本及自动编译安装apache
- BOM基础二
- linux 下解压命令大全
- D.8前导0的数字
- Java线程模型
- 【jzoj3773】【NOI2015模拟8.15】【小 P 的烦恼】【动态规划】
- OpenCV中ORB实时匹配
- 沃顿商学院自我管理课——技能与练习
- 《Angular之简介》
- IO流——自定义装饰类
- android的应用架构和常用库
- python高级特性
- [python]你有一个目录,放了你一个月的日记,都是 txt,为了避免分词的问题,假设内容都是英文,请统计出你认为每篇日记最重要的词。
- CI框架多文件上传以及优化上传方法