bzoj 1894 游戏
题目大意:
$n$个装备,每个装备有两个值,可以攻击该值对应的怪兽。每个装备最多用一次
每个怪兽被打一次之后就会死,每个怪兽可以被打当且仅当前面的都死了,求最多打多少个
思路:
很明显的二分图匹配,如果用$Dinic$的时候一条一条加入连向终点的边即可
但是为什么这道题我$TLE$了啊 垃圾Dinic要你有何用,我也不(wang)会(le)匈牙利啊
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define ll long long
#define db double
#define inf 2139062143
#define MAXN 4010
#define MOD 1000000007
#define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
#define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
#define ren for(register int i=fst[x];i;i=nxt[i])
#define pb(i,x) vec[i].push_back(x)
#define pls(a,b) (a+b+MOD)%MOD
#define mns(a,b) (a-b+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,s,t;
struct Dinic
{
int fst[MAXN],nxt[MAXN<<],to[MAXN<<],val[MAXN<<],cnt;
int S,T,vis[MAXN],tot,cur[MAXN],q[MAXN],l,r,dis[MAXN];
Dinic(){memset(fst,,sizeof(fst));cnt=;}
void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
void ins(int u,int v,int w) {add(u,v,w);add(v,u,);}
int bfs()
{
q[l=r=]=T,vis[T]=++tot,dis[T]=;int x;
while(l<=r)
{
x=q[l++];cur[x]=fst[x];ren if(vis[to[i]]!=tot&&val[i^])
vis[to[i]]=tot,dis[to[i]]=dis[x]+,q[++r]=to[i];
}
return vis[S]==tot;
}
int dfs(int x,int a)
{
if(x==T||!a) return a;int f,flw=;
for(int& i=cur[x];i&&a;i=nxt[i])
if(val[i]&&dis[to[i]]==dis[x]-&&(f=dfs(to[i],min(a,val[i]))))
val[i]-=f,val[i^]+=f,flw+=f,a-=f;return flw;
}
int solve(int s,int t,int res=)
{S=s,T=t;while(bfs()) res+=dfs(S,inf);return res;}
}D;
int main()
{
n=read(),m=read(),s=,t=n+m+;int a,b;rep(i,,m)
{a=read()+,b=read()+;D.ins(a,i+n,);D.ins(b,i+n,);}
rep(i,,n) D.ins(s,i,);
rep(i,,m+) {D.ins(i+n,t,);if(!D.solve(s,t)) return printf("%d\n",i-),;}
}
bzoj 1191 代码(与此题只是数据范围区别
然后发现了奇妙的并查集做法
对每个装备的两个值连边,若形成一个$x$个点的树,则我们可以选走$x-1$个点,留下最大的那个
若成环,则都可以取。这样我们并查集合并即可,合并时找出最大的不行变成可以的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define ll long long
#define db double
#define inf 2139062143
#define MAXN 1001000
#define MOD 1000000007
#define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
#define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
#define ren for(register int i=fst[x];i;i=nxt[i])
#define pb(i,x) vec[i].push_back(x)
#define pls(a,b) (a+b+MOD)%MOD
#define mns(a,b) (a-b+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,fa[MAXN],ok[MAXN];
int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
int main()
{
n=read(),m=;int a,b;rep(i,,m) fa[i]=i;rep(i,,n)
{
a=find(read()),b=find(read());if(a==b) {ok[a]=;continue;}
if(a>b) swap(a,b);ok[!ok[a]?a:b]=,fa[a]=b;
}rep(i,,m+) if(!ok[i]) return printf("%d\n",i-),;
}
bzoj 1894 游戏的更多相关文章
- bzoj 5288 游戏
bzoj 5288 游戏 显然从点 \(x\) 出发,能到达的点是包含 \(x\) 的一段区间.用 \(L,R\) 两个数组记录每个点对应的区间端点. 如果能预处理出 \(L,R\) ,询问显然可以 ...
- bzoj 1854 游戏 二分图匹配 || 并查集
题目链接 Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的 ...
- BZOJ 1854 游戏
Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有\(2\)个属性,这些属性的值用\([1,10000]\)之间的数表示.当他使用某种装备时,他只能使用该 ...
- BZOJ 1025 游戏
Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对 ...
- BZOJ 1443 游戏(二分图博弈)
新知识get. 一类博弈问题,基于以下条件: 1.博弈者人数为两人,双方轮流进行决策.2.博弈状态(对应点)可分为两类(状态空间可分为两个集合),对应二分图两边(X集和Y集).任意合法的决策(对应边) ...
- bzoj 4465 游戏中的学问
Written with StackEdit. Description 大家应该都见过很多人手拉手围着篝火跳舞的场景吧?一般情况下,大家手 拉手跳舞总是会围成一个大圈,每个人的左手拉着旁边朋友的右手, ...
- bzoj 4457: 游戏任务
4457: 游戏任务 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 128 Solved: 71[Submit][Status][Discuss] D ...
- BZOJ 1854 游戏(二分图匹配或并查集)
此题的二分图匹配做法很容易想,就是把属性当做s集,武器当做t集,如果该武器拥有该武器则连一条边. 那么答案就是求该二分图的最大前i个匹配.将匈牙利算法改一改,当前找不到增广路就break. 但是过这个 ...
- BZOJ 1025 游戏(分组背包)
题目所谓的序列长度实际上就是各循环节的lcm+1. 所以题目等价于求出 一串数之和等于n,这串数的lcm种数. 由唯一分解定理可以联想到只要把每个素数的幂次放在一个分组里,然后对整体做一遍分组背包就行 ...
随机推荐
- elasticsearch入门使用(三) Query DSL
Elasticsearch Reference [6.2] » Query DSL 参考官方文档 :https://www.elastic.co/guide/en/elasticsearch/refe ...
- 阻塞IO下的echo回显实验
我们只关心代码中的业务逻辑和底层阻塞原因 客户端代码 发送数据 std::string message(len, 'S'); int nw = stream->sendAll(message.c ...
- P1364 医院设置 洛谷
https://www.luogu.org/problem/show?pid=1364 题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口.圈边上数字表示结点编号,现在要求在某个结 ...
- Codeforces 518 D Ilya and Escalator
Discription Ilya got tired of sports programming, left university and got a job in the subway. He wa ...
- Loj #6307. 「雅礼国庆 2017 Day1」Clique
link: https://loj.ac/problem/6307 最大团转补图的独立集,这样的话只有r[x]<l[y]或者r[y]<l[x],x和y才能连边,所以排序之后乱搞就行了. 需 ...
- ByteArrayInputStream的作用,和BufferedOutputStream 的区别
个人好奇ByteArrayInputStream,到底是有什么用于是百度了一些资料 整合了下,********这两个类对于要创建临时性文件的程序以及网络数据的传输.数据压缩后的传输等可以提高运行的的效 ...
- hdu1385Minimum Transport Cost(最短路变种)
题目链接: huangjing 思路: 输出路径的最短路变种问题..这个题目在于多组询问.那么个人认为用floyd更加稳妥一点.还有就是在每一个城市都有过路费,所以在floyd的时候更改一下松弛条件就 ...
- C#代码调用页面javascript函数
C#代码调用javascript函数 前台<%@ Page Language="C#" AutoEventWireup="true" CodeFile ...
- 带您了解Oracle层次查询
http://database.51cto.com/art/201010/231539.htm Oracle层次查询(connect by )是结构化查询中用到的,下面就为您介绍Oracle层次查询的 ...
- Coursera 机器学习Course Wiki Lecture Notes
https://share.coursera.org/wiki/index.php/ML:Main 包含了每周的Lecture Notes,以便复习回顾的时候使用.