[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 ...
随机推荐
- HDU 2588 GCD(欧拉函数)
GCD Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- DDD实践:领域事件
要求:修改good表,添加 organization 基础定义 用于引发和调度事件的延迟方法 AddDomainEvent Domain\SeedWork\Entity.cs public abstr ...
- 牛客网练习赛t2(线段树)
题解: 好像因为他说了 数据范围全部在ll以内 所以直接暴力就可以过了 比较正常是用线段树来维护 洛谷上有道模板题是支持加,乘,区间和 而这题还多了区间平方和的操作 按照那题的操作 我们维护的时候保证 ...
- redis 在 php 中的应用
一.redis 在 php 中的应用(Key篇) 二.redis 在 php 中的应用(String篇) 三.redis 在 php 中的应用(Hash篇) 四.redis 在 php 中的应用(Li ...
- Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈
原文链接https://www.cnblogs.com/zhouzhendong/p/CF781E.html 题目传送门 - CF781E 题意 有一个矩形,宽为 w ,高为 h .一开始会有 w 个 ...
- BZOJ1095 [ZJOI2007]Hide 捉迷藏 动态点分治 堆
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ1095.html 题目传送门 - BZOJ1095 题意 有 N 个点,每一个点是黑色或者白色,一开始所 ...
- youDao
2018-09-22Journeys end in lovers' meeting.漂泊止于爱人的相遇. All extremes of feeling are allied with madness ...
- logging日志文件配置
Django配置如下 简洁版: LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console' ...
- mybatis的xml处理大于和小于号问题
https://blog.csdn.net/u022812849/article/details/42123007
- mybatis相关知识
@param解释为映射mapper.xml中的传参 mybatis中批量新增时用foreach循环,注意其中的collection属性,有list,数组 注意foreach中sql函数的写法,orac ...