【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的值的个数.现在要求寻找最小步数,显然要减去一 ...
随机推荐
- 《从零开始学Swift》学习笔记(Day 38)——构造函数与存储属性初始化
原创文章,欢迎转载.转载请注明:关东升的博客 构造函数的主要作用是初始化实例,其中包括:初始化存储属性和其它的初始化.在Rectangle类或结构体中,如果在构造函数中初始化存储属性width和hei ...
- B - Catch That Cow (抓牛)
B - Catch That Cow Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u ...
- linux 服务器所支持的最大句柄数调高数倍(与服务器的内存数量相关)
https://github.com/alibaba/p3c/blob/master/阿里巴巴Java开发手册(详尽版).pdf 2. [推荐]调大服务器所支持的最大文件句柄数(File Descri ...
- Hash表的C++实现(转)
原文:Hash表(C++实现) 哈希表的几个概念: 映像:由哈希函数得到的哈希表是一个映像. 冲突:如果两个关键字的哈希函数值相等,这种现象称为冲突. 处理冲突的几个方法: 1.开放地址法:用开放地址 ...
- Python代码实现删除一个list里面的重复元素
lst=[11,22,33,44,22,11,22,44] print(list(set(lst))) # 打印结果:[33, 11, 44, 22] d = {} for index,item in ...
- javascript实例:点亮灯泡
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android系统移植与调试之------->如何修改Android手机NFC模块,使黑屏时候能够使用NFC
我们都知道在不修改源代码的情况下,只能是解锁之后才能使用NFC功能.而在锁屏和黑屏2个状态下是没办法用NFC的,但是最近有个客户要求手机在黑屏状态下能够使用NFC,因此我们需要去修改Android源代 ...
- 常用模块一(os模块、序列化模块(json和pickle))
一.os模块 os模块是与操作系统交互的一个接口. import os # 和文件和文件夹的操作有关 os.makedirs('dirname1/dirname2') # 可生成多层递归目录 os.r ...
- leetcode第一刷_Rotate Image
这个题该怎么说呢.旋转又要求inplace.一般就是要找到某种规律了.这个还是非常明显的,画一下原来的.再画一下旋转之后的.看看原来的跑到什么位置了. 牵扯到四个位置按顺时针方向互换一下位置,发现仅仅 ...
- [二次开发]dede文章页面怎样显示作者的头像
dede在文章页面显示作者仅仅是显示其username,可是假如我想把dede改造成较为社交化的站点.我认为是有必要显示作者的头像的,可是官方并没有相应的模版标签. 在网上看到解决问题的办法基本上是直 ...