【BZOJ1854】游戏[SCOI2009](神奇贪心+并查集)
这道题和今年GDKOI的Day2T2很像(然而gdkoi的题用网络流可以A,这道题只能拿30)。
网址:http://www.lydsy.com/JudgeOnline/problem.php?id=1854
题目:

很显然,我们可以立即想到一种解法:如果第i个武器的属性是(a,b),那么就连i->a,i->b两条边,然后就跑网络流。为了确保要从1开始连续攻击,就可以二分答案,用网络流来判断,因为如果能从1打到n,就肯定能从1打到n-1(废话)。判断就是每次只让1~mid的属性值流过去,看一下最后的最大流是否为mid,就知道能不能从1打到mid。
代码:
var f,d,q,x,y:array[..]of longint;
a,b,ne:array[..]of longint;
n,k,nn,i,j,h,t,p,l,r,m,ans:longint;
procedure add(x,y,z:longint);
begin
a[p]:=y; b[p]:=z; ne[p]:=f[x]; f[x]:=p; inc(p);
a[p]:=x; b[p]:=; ne[p]:=f[y]; f[y]:=p; inc(p);
end;
function dfs(now,ll:longint):longint;
var i,p:longint;
begin
if now=nn then exit(ll); i:=f[now];
while i>= do begin
if(b[i]>)and(d[a[i]]=d[now]+)then begin
if ll<b[i] then p:=dfs(a[i],ll)
else p:=dfs(a[i],b[i]);
b[i]:=b[i]-p; b[i xor ]:=b[i xor ]+p;
if p> then exit(p);
end;
i:=ne[i];
end;
exit();
end;
begin
read(n);
for i:= to n do read(x[i],y[i]);
l:=; r:=; nn:=n+;
while l+<r do begin
p:=; m:=(l+r)>>;
for i:= to nn do f[i]:=-;
for i:= to n do begin
add(i,n+x[i],); add(i,n+y[i],);
end;
for i:= to n do add(,i,);
for i:= to m do add(n+i,nn,);
ans:=;
while true do begin
for i:= to nn do d[i]:=;
h:=; t:=; q[]:=; d[]:=;
repeat
i:=f[q[h]];
while i>= do begin
if(b[i]>)and(d[a[i]]=)then begin
inc(t); q[t]:=a[i]; d[a[i]]:=d[q[h]]+;
end;
i:=ne[i];
end;
inc(h);
until h>t;
if d[nn]= then break;
repeat
p:=dfs(,<<);
ans:=ans+p;
until p=;
end;
if m=ans then l:=m else r:=m;
end;
writeln(l);
end.
然而……这只是30%的解法。
100%的解法。。。应该怎么说呢。。。并查集+神奇贪心?
参考黄学长的博客:http://hzwer.com/2950.html
其实就是把属性为(a,b)的武器看成一条边,然后就生成了一个有10000个结点的无向图,于是我们就要把点和边进行配对(就像上面的二分图匹配一样)。对于其中每一个联通块,有两种情况:
1、假设它有k个节点,如果有k-1条边,那么肯定有一个节点匹配不到(把它看成一棵有根树,每个节点匹配他的父亲)。为了确保答案最优,那么我们就把这个不能被匹配到的节点定为这个联通块中属性值最大的节点。
2、如果这个联通块中有>=k条边,这个联通块中就存在环,一定能把全部的点都找到匹配的边(看成环套树,环上的节点一定能被匹配到,而环上的树就按照第一种情况匹配)
于是就可以用并查集,每次往图中增加一条边时,如果这两个点在同一个联通块,那么这个联通块的根就可以被匹配(这个联通块在加边之后一定成为第二种情况),否则判断是否两个联通块是否有一个存在环(一个有环图无论怎么加还是有环)(我一开始就被这个坑了),否则把编号较小的点修改为可以被匹配,然后把它接到编号较大的点上。这样处理,就可以使每个联通块中最多有一个节点不能被选择,而这个不能被选择的点一定是该联通块中编号最大的节点。最后扫一遍就好了。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int f[],v[]={};
int find(int x)
{
if(f[x]=x)return x;
int ret=find(f[x]); f[x]=ret;
return ret;
}
int main()
{
int n,i,x,y;
scanf("%d",&n);
for(i=;i<=n+;i++) f[i]=i;
for(i=;i<=n;i++){
scanf("%d%d",&x,&y);
int fx=find(x),fy=find(y);
if(fx==fy)v[fx]=;
else {
if(fx>fy){
int t=fx; fx=fy; fy=t;
}
if(v[fx])v[fy]=;else v[fx]=;
f[fx]=fy;
}
}
int ans=;
while(v[ans]&&ans<=n)ans++;
printf("%d",ans-);
}
P.S. 当我做这道题时,ZN大神犇看了一眼后,说:“这不是傻逼贪心吗?” orz orz orz ZN大神犇
【BZOJ1854】游戏[SCOI2009](神奇贪心+并查集)的更多相关文章
- BZOJ-1854 游戏 二分图匹配 (并查集)
1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 3372 Solved: 1244 [Submit][Status] ...
- bzoj1854 游戏题解(二分图/并查集)
1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 5547 Solved: 2229[Submit][Status] ...
- [BZOJ1854][Scoi2010]游戏(二分图匹配/并查集)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1854 分析:很裸的一道二分图匹配对吧,但是在hzwer的blog上看见神奇的并查集做法 ...
- POJ 1456 Supermarket(贪心+并查集)
题目链接:http://poj.org/problem?id=1456 题目大意:有n件商品,每件商品都有它的价值和截止售卖日期(超过这个日期就不能再卖了).卖一件商品消耗一个单位时间,售卖顺序是可以 ...
- poj1456(贪心+并查集)
题目链接: http://poj.org/problem?id=1456 题意: 有n个商品, 已知每个商品的价格和销售截止日期, 每销售一件商品需要花费一天, 即一天只能销售一件商品, 问最多能买多 ...
- Codeforces 437D The Child and Zoo(贪心+并查集)
题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路 ...
- POJ - 1456 贪心+并查集
做法一:直接贪心,按照利润排序,然后直接尽量给每个活动安排到最晚的时间即可.时间复杂度O(n * d)当d都为10000时,很容易超时.由于这题数据比较水,所有贪心未超时. AC代码 #include ...
- poj1456 Supermarket 贪心+并查集
题目链接:http://poj.org/problem?id=1456 题意:有n个物品(0 <= n <= 10000) ,每个物品有一个价格pi和一个保质期di (1 <= pi ...
- GYM 101173 F.Free Figurines(贪心||并查集)
原题链接 题意:俄罗斯套娃,给出一个初始状态和终止状态,问至少需要多少步操作才能实现状态转化 贪心做法如果完全拆掉再重装,答案是p[i]和q[i]中不为0的值的个数.现在要求寻找最小步数,显然要减去一 ...
随机推荐
- Tomcat工作原理解析!
Tomcat简介 作者:杨晓(http://blog.sina.com.cn/u/1237288325) 一.Tomcat背景 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Gro ...
- 46、PopWindow工具类
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...
- Cocos2d-x Lua中帧动画
帧动画就是按一定时间间隔.一定的顺序.一帧一帧地显示帧图片.我们的美工要为精灵的运动绘制每一帧图片,因此帧动画会由很多帧组成,按照一定的顺序切换这些图片就可以了. 在Cocos2d-x Lua中播放帧 ...
- eclipse content assist 出现错误
解决方法是,在Window->preference->java->editor>Content Assist->advanced ,将 time out 由50 ms 改 ...
- 类 String、StringBuffer、StringBuilder
类 String String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现.字符串是常量:它们的值在创建之后不能更改.字符串缓冲区支持 ...
- 介绍一下Python中webbrowser的用法?
webbrowser模块提供了一个高级接口来显示基于Web的文档,大部分情况下只需要简单的调用open()方法.webbrowser定义了如下的异常:exception webbrowser.Erro ...
- 在cli命令行上显示当前数据库,以及查询表的行头信息
在$HIVE_HOME/conf/hive-site.xml文件下加入以下配置文件 <property> <name>hive.cli.print.header</nam ...
- 江卓尔与比特币增发,谣言or先知-千氪
最近,很多圈内人都在讨论比特币是否应该增发,但等等,比特币真的会增发吗?到底是真有增发计划还是某些人别有用心地在散布谣言? 那么消息是从哪里出来的?北京时间 2 月 10 日晚,莱比特矿池创始人江卓尔 ...
- 74LS85 比較器 【数字电路】
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u011368821/article/details/27959219 74LS85 demo: 11 ...
- Ubuntu16.04安装Chrome浏览器及解决root不能打开的问题
1. 安装桌面(emmm,不知道是否只执行第二个命令就行) # apt-get install gonme# apt-get install ubuntu-desktop2. 安装Chrome浏览器 ...