Description
lxhgww
最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有
2
个属性,这些属性的值用
Input
输入的第一行是一个整数
N
,表示
接下来
Output
输出一行,包括
1
个数字,表示
SampleInput
3
2
【数据范围】
对于
30%
的数据,保证
N≤1000
对于
100%
的数据,保证
N≤1000000
Source
Day1
Solution
这题有并查集做法,见黄学长博客。
传送门http://hzwer.com/2950.html
如果不嫌我方法麻烦就看下去吧。
因为攻击一次需要一个装备,即我们最后求得的是一个第 k <script id="MathJax-Element-1078" type="math/tex">k</script>次攻击与装备的匹配关系。
不能跳过某次攻击,也就是说,我们要得到一个攻击次数从小到大全部(最多)能与装备匹配的方案。
那么思路就很清晰了,每一个匹配边表示使用某个装备解决某次攻击。
要求的就是从一开始连续能匹配掉多少个属性值。
首先这是个二分图,然后匈牙利在匹配时不会使之前已经匹配的左子图(即开始搜索的子图)点失配。
所以第几次攻击与武器连边,匈牙利解决。
#include<cstdio>
#include<cstring>
#define M 1020000
using namespace std;
struct edge{int v,n;}e[M<<2];
int link[M],n,x,y,tot,s[M],t=1,time[M];
bool dfs(int u)
{
for(int i=s[u];i;i=e[i].n)
{
int v=e[i].v;
if(time[v]!=t)
{
time[v]=t;
if(link[v]==0 || dfs(link[v]))
{
link[v]=u;
return 1;
}
}
}
return 0;
}
inline void push(const int &u,const int &v){e[++tot].v=v;e[tot].n=s[u];s[u]=tot;}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
push(i,x+n);push(i,y+n);push(x+n,i);push(y+n,i);
}
for (int i=n+1;i<=n+10000;i++,t++)
{
time[i]=t;
if (!dfs(i))
{
printf("%d",i-n-1);
return 0;
}
}
puts("10000");
}