【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的值的个数.现在要求寻找最小步数,显然要减去一 ...
随机推荐
- ScheduleFactory(不同scheduler name)
package com.unis.uvm.quartz; import java.util.Properties; import org.quartz.Scheduler; import org.qu ...
- PHPStorm2017去掉参数提示 parameter name hints
JetBrains 的各种语言的 IDE 都灰常灰常好用, 个个都是神器, PHPStorm 作为PHP开发的神器也不必多说了 今天升级到 PHPStorm 2017.1 发现增加了好些新功能, 有个 ...
- C++ 基础知识回顾(string基础、智能指针、迭代器、容器类)
[1] string基础 [1.1] string 的构造 #include <iostream> #include <string> int main() { using n ...
- 【BZOJ1812】[Ioi2005]riv 树形DP
[BZOJ1812][Ioi2005]riv Description 几乎整个Byteland王国都被森林和河流所覆盖.小点的河汇聚到一起,形成了稍大点的河.就这样,所有的河水都汇聚并流进了一条大河, ...
- docker-compose安装confluence
1.首先安装docker-compose pip install docker-compose 安装完成提示: 2.编写mysql-confluence-compose ...
- 160819、JavaScript-数组去重由慢到快由繁到简
JavaScript-数组去重由慢到快由繁到简演化 indexOf去重 Array.prototype.unique1 = function() { var arr = []; for (var ...
- http-proxy-middleware使用方法和实现原理(源码解读)
本文主要讲http-proxy-middleware用法和实现原理. 一 简介 http-proxy-middleware用于后台将请求转发给其它服务器. 例如:我们当前主机A为http://loca ...
- JS基础知识简介
使用js的三种方式 1.HTML标签内嵌js <button onclick="javascript:alert(真点啊)">有本事点我</button> ...
- Navicat for MySQL远程连接虚拟机
在虚拟机中进入mysql mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT O ...
- (转)fiddler使用简介--其一
原文地址:https://www.cnblogs.com/miantest/p/7289694.html Fiddler基础知识 Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行 ...