[BZOJ 1854] SCOI 2010 游戏 · 二分图匹配
2015-03-10 21:26
519 查看
二分图匹配。
左边的点表示属性,右边的点表示武器编号,每次读入将武器和对应属性之间连边,然后从1-10000枚举属性值,如果某个属性值没有匹配到武器那么就退出循环,输出上一个属性值。为了防止第10000属性也可以满足,要枚举到10001。另外笔者蒟蒻……第一遍交跑出个TLE,然后重新看了一下匈牙利发现,我们把vis数组的职能从bool类型改成了int类型,对于第k个属性值,每次访问到一个武器i时,如果vis[i]==k就说明本次搜索这个点已经搜过了,否则记录一下vis[i]=k,防止重复搜索,这样就可以不要每次都memset。
左边的点表示属性,右边的点表示武器编号,每次读入将武器和对应属性之间连边,然后从1-10000枚举属性值,如果某个属性值没有匹配到武器那么就退出循环,输出上一个属性值。为了防止第10000属性也可以满足,要枚举到10001。另外笔者蒟蒻……第一遍交跑出个TLE,然后重新看了一下匈牙利发现,我们把vis数组的职能从bool类型改成了int类型,对于第k个属性值,每次访问到一个武器i时,如果vis[i]==k就说明本次搜索这个点已经搜过了,否则记录一下vis[i]=k,防止重复搜索,这样就可以不要每次都memset。
#include <stdio.h> #include <algorithm> #include <string.h> using namespace std; const int maxn=5000005; int n,m,match[maxn],vis[maxn],x,y,k; int node[maxn],next[maxn],head[maxn],tot; int get(){ int p=0;char x=getchar(); while (x<'0' && x>'9') x=getchar(); while (x>='0' && x<='9') p=p*10+x-'0',x=getchar(); return p; } void add(int x,int y){ node[++tot]=y; next[tot]=head[x]; head[x]=tot; } bool dfs(int x){ for (int i=head[x];i;i=next[i]) if (vis[node[i]]!=k){ vis[node[i]]=k; if (!match[node[i]] || dfs(match[node[i]])){ match[node[i]]=x; return 1; } } return 0; } int main(){ n=get();tot=0; memset(head,0,sizeof head); memset(vis,0,sizeof vis); for (int i=1;i<=n;i++){ x=get();y=get(); add(x,i);add(y,i); } for (k=1;k<=10001;k++) if (!dfs(k)) break; printf("%d",k-1); return 0; }
相关文章推荐
- 【BZOJ 1854】【SCOI 2010】游戏【并查集 & 二分图匹配】
- BZOJ 1854: [Scoi2010]游戏 [连通分量 | 并查集 | 二分图匹配]
- [BZOJ1854][Scoi2010]游戏(二分图匹配)
- 【bzoj1854 Scoi2010】游戏(二分图匹配)
- BZOJ 1854 [Scoi2010]游戏——二分图匹配
- [二分图匹配] bzoj1854: [Scoi2010]游戏
- [SCOI2010][BZOJ1854] 游戏|二分图匹配|匈牙利算法|并查集
- 【bzoj1854】 SCOI2010游戏 二分图匹配
- BZOJ 1854 [Scoi2010]游戏 二分图匹配
- BZOJ 1854: [Scoi2010]游戏 二分图匹配
- BZOJ1854 [Scoi2010]游戏(并查集/二分图匹配)
- 【bzoj 1854】[Scoi2010]游戏 二分图匹配
- bzoj1854 [Scoi2010]游戏 二分图匹配 并查集
- BZOJ 1854: [Scoi2010]游戏( 二分图最大匹配 )
- bzoj 1854: [Scoi2010]游戏(二分图的最大匹配)
- [BZOJ1854][Scoi2010]游戏(二分图)
- BZOJ 1854[Scoi2010]游戏
- BZOJ 1854 [Scoi2010] 游戏 题解与分析
- BZOJ 1854|SCOI 2010|游戏|并查集
- 【二分图最大匹配】[SCOI2010] 游戏 BZOJ 1854