GDKOI2015D2T1
2016-01-27 13:46
225 查看
题目大意:有一个二分图,对于左边的第i个点,权值为a[i],右边的第i个点权值b[i]。现图中有m条边,第i条边连接s[i],t[i]两点,权值为a[s[i]]+b[s[i]],选择其中若干条边,使总权值最大,但是选出来的边两两不相交。
这道题近似于codevs上的线段覆盖,于是在实现上我们也用上一个近似于线段覆盖的方法来完成这道题(好扯淡……):
1. 读入全部数据
2. 将所有的边以起点为第一关键字(升序),终点为第二关键字(降序)进行排序
3. DP,f[i]表示在右边前i个点(包括i)的最大权值,那么我们有
f[t[i]]= max(f[t[i]],a[s[i]]+b[t[i]]) (t[i]=1)
max(f[t[i]],max{f[t[i]-1]}+a[s[i]]+b[t[i]]) (t[i]>1)
那么,麻烦就麻烦在不能直接把前t[i]-1个点里面的最大f值用打擂台的方式找出来,那么怎么办呢?用线段树进行优化。在第3步里面,先把后面的公式的值用k存起来,如果k>f[t[i]],那么f[t[i]]=k再把f[t[i]]存入线段树中。这样一来,我们在求t[i]>1的k值的时候就可以大大加快速度
OK,上代码:
这道题近似于codevs上的线段覆盖,于是在实现上我们也用上一个近似于线段覆盖的方法来完成这道题(好扯淡……):
1. 读入全部数据
2. 将所有的边以起点为第一关键字(升序),终点为第二关键字(降序)进行排序
3. DP,f[i]表示在右边前i个点(包括i)的最大权值,那么我们有
f[t[i]]= max(f[t[i]],a[s[i]]+b[t[i]]) (t[i]=1)
max(f[t[i]],max{f[t[i]-1]}+a[s[i]]+b[t[i]]) (t[i]>1)
那么,麻烦就麻烦在不能直接把前t[i]-1个点里面的最大f值用打擂台的方式找出来,那么怎么办呢?用线段树进行优化。在第3步里面,先把后面的公式的值用k存起来,如果k>f[t[i]],那么f[t[i]]=k再把f[t[i]]存入线段树中。这样一来,我们在求t[i]>1的k值的时候就可以大大加快速度
OK,上代码:
type tpoint=^tppoint; tppoint=record l,r,mid:longint; max:longint; lc,rc:tpoint; end; edge=record s,t:longint;end; var e:array[1..500000]of edge; p,q,f:array[1..100000]of longint; head:tpoint; n,m,i,j,k:longint; procedure sort(l,r: longint); var i,j:longint;x,y:edge; begin i:=l; j:=r; x:=e[(l+r) div 2]; repeat while (e[i].s<x.s)or(e[i].s=x.s)and(e[i].t>x.t) do inc(i); while (x.s<e[j].s)or(x.s=e[j].s)and(x.t>e[j].t) do dec(j); if not(i>j) then begin y:=e[i]; e[i]:=e[j]; e[j]:=y; inc(i); j:=j-1; end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; procedure build(var p:tpoint;l,r:longint); begin new(p); p^.l:=l; p^.r:=r; p^.mid:=(l+r)div 2; if l=r then begin p^.max:=0; p^.lc:=nil; p^.rc:=nil; exit; end; build(p^.lc,l,p^.mid); build(p^.rc,p^.mid+1,r); p^.max:=0; end; procedure update(var p:tpoint;x,value:longint); begin if p^.l=p^.r then begin p^.max:=value; exit; end; if x<=p^.mid then update(p^.lc,x,value) else update(p^.rc,x,value); p^.max:=max(p^.lc^.max,p^.rc^.max); end; function query(p:tpoint;l,r:longint):Longint; var ans:longint; begin if l>r then exit(0); if p=nil then exit(0); if p^.r<=r then exit(p^.max); ans:=query(p^.lc,l,r); if p^.mid+1<=r then ans:=max(ans,query(p^.rc,l,r)); exit(ans); end; begin read(n,m); if m=0 then begin writeln(0); exit; end; build(head,1,n); for i:=1 to m do read(e[i].s,e[i].t); for i:=1 to n do read(q[i]); for i:=1 to n do read(p[i]); sort(1,m); for i:=1 to m do begin if e[i].t<>1 then k:=query(head,1,e[i].t-1)+p[e[i].s]+q[e[i].t] else k:=p[e[i].s]+q[1]; if k>f[e[i].t] then begin update(head,e[i].t,k); f[e[i].t]:=k; end; end; writeln(query(head,1,n)); end.代码片:https://code.csdn.net/snippets/1567138
相关文章推荐
- TextureView+MediaPlayer播放本地视频
- Spring的XML配置的bean调用注解方式的bean
- win下直播环境的搭建
- Lua 笔记
- iOS网络编程实践--蓝牙对等网络通信实例讲解
- linux之device_init()
- The user specified as a definer ('montor'@'%') does not exist
- 20条Linux命令面试问答
- 自定义复选框 checkbox 样式
- Unity关于用LoadLevelAdditiveAsync导致新场景的Navmesh数据不正确Loading条的实践
- 高效动画
- Exchange 2007(二)原域控降级新域控更改IP和计算机名
- java 死记硬背真不行
- (转)String和StringBuilder、StringBuffer的区别?
- 项目功能大全,让你的项目一天搞定
- LayoutInflater源码深度分析笔记
- AlertDialog创建过程详解
- CareerCup All in One 题目汇总 (未完待续...)
- HDU 1029 Ignatius and the Princess IV
- iOS 蓝牙使用小结 bluetooth