[jzoj]1729.blockenemy
Link
https://jzoj.net/senior/#main/show/1729
Description
你在玩电子游戏的时候遇到了麻烦。。。。。。
你玩的游戏是在一个虚拟的城市里进行,这个城市里有n个点,都从0~n-1编了号,每两个点之间有且仅有一条路径。现在,你的敌人到这个城市来踩点了!!!为了阻止他们更好的踩点, 你决定切断他们所有踩点人员的联系,使他们孤军作战,然后在各个击破。但是这就要切断某些街道,而你每切断一条路,市民就会产生相对的不满值,不满值越大,城市的和谐度就越小。
所以你现在需要知道为了使踩点人员所在的点两两之间不联通所切断的边产生的最小不满值是多少?
Solution
40分
判断每条边选不选,就可以了
100分
这道题是一道很好的树形DP练手题目,同时也可以用并查集+贪心来做,现在讲一下两种做法
(1)树形DP
设f[x]表示以x为根,它子树的敌人都不可以互相联络,且无法到达点x的最小价值
设g[x]表示以x为根,它子树的敌人都不可以互相联络,但是其中一个敌人可以到达x这个点的最小价值
这个状态设得异常巧妙,在我看过这道题的所有题解,这是最好理解的
其实,解题的关键,就是状态和转移上面了!
我们考虑两种情况,如果当前x上有敌人,或者没有敌人,应该怎么做。
①有敌人
如果有敌人,那么f[x]就赋值为无穷大,因为他根本不可以“无法到达点x”
这时,我们考虑g[x]给之后的转移用,到底g[x]应该是多少
显然是g[x]=∑min(f[y],g[y]+dis[x,y]),(y是x的儿子)为什么呢?
因为x这个点有敌人了,那么g[x]本身就符合条件了
因为f[y]的时候,没有点可以互相联络,如果多添一个点x,那么他就是g[x]的条件了,所以它是取最小值的两个数之一
因为g[y]已经符合条件了,如果多添一个点x,那么他就不符合g[x]的条件了,因为他有2个点可以到达x,所以我们需要x~y之间连一条边,保证只有1个点可以到达x
②无敌人
f[x]=∑min(f[y],g[y]+dis[x,y])(y是x的儿子)为什么呢?
跟上面g数组的转移差不多
f[y]是符合条件的,所以多添一个点还是fx的条件,所以是取最小值的两个数之一、
g[y]是不符合条件的,他有1个点可以到达x,所以x~y之间连一条边,保证没有点可以到达x
可是,这时,g[x]怎么做的?怎么转移是本题解题的关键所在
g[x]一定是在f[x]的基础上转移的!使得它的某个儿子不可以到达
其实,就是把f[x]中,一个花费最大的一次删除敌人到x的边的价值,删掉
重点
上面说了f[x]=min(f[y],g[y]+dis[x,y])(其中一个),我们把可以到达x这个点,变成不可以到达这个点,然后就有两种情况
一种就是g[y]+dis,如下图
试想一下,原本y点为根的子树是可以到达y的,但是删去了x~y之间的边就不可以到达了,也就是说,是从未知点~x~y的,是这样的顺序
还有一种情况就是f[y],同上图
就是原本的
我们由min(g[y]+dis,f[y])变成g[y]就是上面所说
f[x]就会在f[x]的基础上减去min(g[y]+ w, f[y]) – g[y],那么这个值越大,f[x]就会越小。
f[x]-g[y]就是那个让原本可以到y的,变成不能到y的那条边,f[x]-这条边的最大值,就是g[x]
显然是取最大值,这样g[x]就变得很小
我发个连续的段子,结合图片和f,g数组的定义看,一定可以看得懂
“G[x]的转移有那么一丢丢难想。G[x]一定实在f[x]的基础上,使得某个儿子从不能到达x,变成能到达x,即儿子y对该状态的贡献由min(g[y] + w, f[y])变为g[x].如果这样的话,f[x]就会在f[x]的基础上减去min(g[y]+ w, f[y]) – g[y],那么这个值越大,f[x]就会越小。”
如果实在看不懂,就看看我那含糊不清的理解,说不定,我们心有灵犀,一语点破。
(2)贪心+并查集
思想跟最小生成树一样,简直一模一样
可以通过O(n^2)判断加多一条边是否可以符合题目条件
边从大到小选
如果n大一点,上面的判断可以改成O(m)的,m是边数,根据深度来搜索每一个点。
Code(3)
树形DP①
uses math;
var
n,i,j,x,y,z:longint;
g,f,e,bz,ok:array[..] of longint;
b,c:array[..,..] of longint;
procedure insert(x,y,z:longint);
begin
inc(b[x,]);
b[x,b[x,]]:=y;
c[x,b[x,]]:=z;
end; procedure dg(x:longint);
var
t,i,tt:longint;
begin
if ok[x]= then
begin
f[x]:=maxlongint;
for i:= to b[x,] do
if bz[b[x,i]]= then
begin
bz[b[x,i]]:=;
dg(b[x,i]); g[x]:=g[x]+min(g[b[x,i]]+c[x,i],f[b[x,i]]);
end;
end
else
begin
t:=;
for i:= to b[x,] do
if bz[b[x,i]]= then
begin
bz[b[x,i]]:=;
dg(b[x,i]); tt:=min(f[b[x,i]],g[b[x,i]]+c[x,i]); f[x]:=f[x]+tt; t:=max(t,tt-g[b[x,i]]); end; g[x]:=f[x]-t;
end;
end; begin
assign(input,'s.in');reset(input);
readln(n);
for i:= to n- do
begin
readln(x,y,z);
insert(x,y,z);
insert(y,x,z);
end; while not eof do
begin
inc(e[]);
readln(e[e[]]);
ok[e[e[]]]:=;
end; bz[]:=;
dg(); writeln(min(f[],g[]));
end.
树形DP②
const maxn=;
var i,n,x,y,l,tot:longint;
yy,next,cost,g,fa,f,gu:array[..maxn] of longint;
t:array[..maxn] of boolean;
function max(x,y:longint):longint; begin if x>y then exit(x);exit(y);end;
function min(x,y:longint):longint; begin if x>y then exit(y);exit(x);end;
procedure make(x,y,l:longint);
begin
inc(tot);
yy[tot]:=y;
next[tot]:=gu[x];
cost[tot]:=l;
gu[x]:=tot;
end;
procedure dfs(x:longint);
var i,j,sum,y:longint;
begin
i:=gu[x];
sum:=;
while i<> do begin
y:=yy[i];
if fa[x]<>y then begin
fa[y]:=x;
dfs(y);
if t[y] then begin
f[x]:=f[x]+f[y]+cost[i];
g[x]:=g[x]+f[y]+cost[i];
sum:=max(sum,cost[i]);
end else begin
f[x]:=f[x]+min(g[y]+cost[i],f[y]);
if g[y]+cost[i]>f[y] then begin
sum:=max(sum,f[y]-g[y]);
g[x]:=g[x]+f[y];
end else begin
sum:=max(sum,cost[i]);
g[x]:=g[x]+g[y]+cost[i];
end;
end;
end;
i:=next[i];
end;
if t[x] then g[x]:=f[x] else g[x]:=g[x]-sum;
end;
begin
readln(n);
for i:= to n- do begin
readln(x,y,l);
make(x+,y+,l);
make(y+,x+,l);
end;
while not eof do begin
readln(x);
t[x+]:=true;
end;
dfs();
writeln(min(f[],g[]));
end.
贪心+并查集
var
bz:boolean;
n,i,j,k,ans:longint;
f,e,qq:array[..] of longint;
a:array[..,..] of longint;
procedure q(l,r:longint);
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(l+r) shr ,];
while i<j do
begin
while a[i,]>mid do inc(i);
while a[j,]<mid do dec(j);
if i<=j then
begin
a[]:=a[i]; a[i]:=a[j]; a[j]:=a[]; inc(i); dec(j);
end;
end; if i<r then q(i,r);
if l<j then q(l,j);
end; function getfather(x:longint):longint;
begin
if f[x]= then exit(x);
f[x]:=getfather(f[x]);
exit(f[x]);
end; procedure he(x,y:longint);
var
fx,fy:longint;
begin
fx:=getfather(x);
fy:=getfather(y);
if fx<>fy then
f[fy]:=fx;
end;
begin
readln(n);
for i:= to n- do
begin
readln(a[i,],a[i,],a[i,]);
inc(a[i,]);
inc(a[i,]);
end; while not eof do
begin
inc(e[]);
readln(e[e[]]);
inc(e[e[]]);
end; q(,n-); for i:= to n- do
begin
qq:=f; if getfather(a[i,])<>getfather(a[i,]) then
he(a[i,],a[i,]); bz:=true;
for j:= to e[] do
for k:= to e[] do
if j<>k then
if getfather(e[j])=getfather(e[k]) then
bz:=false;
if not bz then
begin
f:=qq;
inc(ans,a[i,])
end;
end; writeln(ans);
end.
[jzoj]1729.blockenemy的更多相关文章
- [BZOJ3223]Tyvj 1729 文艺平衡树
[BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...
- BZOJ3223: Tyvj 1729 文艺平衡树 [splay]
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3595 Solved: 2029[Submit][Sta ...
- BZOJ 3223: Tyvj 1729 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3628 Solved: 2052[Submit][Sta ...
- zoj 3673 1729
1729 Time Limit: 3 Seconds Memory Limit: 65536 KB 1729 is the natural number following 1728 and ...
- bzoj 3223/tyvj 1729 文艺平衡树 splay tree
原题链接:http://www.tyvj.cn/p/1729 这道题以前用c语言写的splay tree水过了.. 现在接触了c++重写一遍... 只涉及区间翻转,由于没有删除操作故不带垃圾回收,具体 ...
- hdoj 1729 Stone Games(SG函数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1729 看了题目感觉像Nim,但是有范围限制,有点不知道SG函数该怎么写 看了题解,最后才明白该怎么去理 ...
- bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2202 Solved: 1226[Submit][Sta ...
- BZOJ 3223: Tyvj 1729 文艺平衡树(splay)
速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...
- 3223: Tyvj 1729 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1347 Solved: 724[Submit][Stat ...
随机推荐
- 处理json大文件
import json import pymysql # 读取review数据,并写入数据库 # 导入数据库成功,总共4736897条记录 def prem(db): cursor = db.curs ...
- config.GetSection(key)编译不通过
要安装这个版本
- MySQL 存储过程与事物
一:存储过程 存储过程可以说是一个记录集吧,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能 存储过程的好处: 1.由于数据库执行动作时,是先编 ...
- Debug.Assert vs Exception Throwing(转载)
来源 Q: I've read plenty of articles (and a couple of other similar questions that were posted on Stac ...
- error: not found: value sqlContext/import sqlContext.implicits._/error: not found: value sqlContext /import sqlContext.sql/Caused by: java.net.ConnectException: Connection refused
1.今天启动启动spark的spark-shell命令的时候报下面的错误,百度了很多,也没解决问题,最后想着是不是没有启动hadoop集群的问题 ,可是之前启动spark-shell命令是不用启动ha ...
- [转] React风格的企业前端技术
亲爱的各位朋友们,大家下午好! 首先祝大家国庆节快乐! 很高兴可以在国庆前夕,可以为大家分享一下React风格的企业前端技术. 谈到前端,可能以前大家的第一感觉就是,前端嘛,无非就是做做页面切图,顶多 ...
- [转] js对象监听实现
前言 随着前端交互复杂度的提升,各类框架如angular,react,vue等也层出不穷,这些框架一个比较重要的技术点就是数据绑定.数据的监听有较多的实现方案,本文将粗略的描述一番,并对其中一个兼容性 ...
- reconnecting-websocket.js
websocket是HTML5下一个不错的网络协议解决方案,有一个场景很多猿猿都会遇到,手机锁屏后大约60秒,IOS会自动断开websocket连接,连接丢失了,那我们的数据也就断了.websocke ...
- 【Arduino】开源开发板说明
来自世界各地的新型微控制器层出不穷,这类开发板多数都是通过Arduino改进的版本,例如由Arduino所改良的Yún一样,主要是针对网状网路进行改进或升级了其它无线功能. 但一些开发板也有着其独到的 ...
- Codeforces 609F Frogs and mosquitoes 线段树
Frogs and mosquitoes 用线段树维护每个点覆盖的最小id, 用multiset维护没有吃的蚊子. #include<bits/stdc++.h> #define LL l ...