【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的值的个数.现在要求寻找最小步数,显然要减去一 ...
随机推荐
- OKhttp3
针对上一博文订单调用用户使用默认数据交互方式,下面介绍下使用 Okhttp3网络数据交换方式. 1.订单启动类变化 package com.tycoon.orderService; import or ...
- K-th Number(主席树)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 59327 Accepted: 20660 Ca ...
- shell脚本中格式化日期
date [-u] [-d datestr] [-s datestr] [--utc] [--universal] [--date=datestr] [--set=datestr] [--help] ...
- IOS自动布局的Problem
今天为做一个小小的footerView我的心脏差点气出来... 第一步 新建一个view xib文件 第二步 新建一个UIview的类 第三步 在UIview中间放一个Lable,添加约束,水平垂直居 ...
- 用户画像 销量预测 微观 宏观 bi
w 目前我们没有自己的平台 第三方平台又不会给任何我们想要的数据 没有用户的注册信息 全天候的行为信息 用户画像没法做 针对我们业务的bi做的思路是什么呢 数据中心怎么做销量预测呢 ...
- 【转】NPIV - 连接虚拟机与存储的桥梁
转自:http://blog.csdn.net/jewes/article/details/7705895 解决什么问题 我们知道在存储区域网络(SAN:storage area network),主 ...
- 全面Python小抄(转)
add by zhj: 有些地方不正确,有时间再改吧 原文:Python Cheat Sheet Cheat sheet of Python. Some basic concepts for Pyth ...
- 0x06 MySQL 单表查询
一 单表查询语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二 关键字 ...
- 检查arg是方法还是函数?
from types import MethodType,FunctionType def check(arg): """ 检查arg是方法还是函数? :param ar ...
- app开发多少钱一个
经常听网友问app开发要多少钱,这个问题太宽泛了,需要根据具体的需求才好定价,也就是要先做好需求分析(前面我们写了一个app开发需求文档模板),不同的功能不同的价位,就像我们买电脑,cpu多少钱.主板 ...