bzoj1854 [Scoi2010]游戏——匈牙利算法
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1854
这题...据说可以用并查集做,但没有去看...
用二分图匹配的话,就把装备和它的两个属性连边,再从属性开始从小到大进行匈牙利算法;
这样可以保证匹配这个属性时先确保前面的都匹配成功了;
所以遇到无法匹配的情况时就结束了,输出即可;
小心TLE,所以避免 memset。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const maxn=1000005,maxm=10005; int n,head[maxm],ct,pre[maxn],mx,ans; int vis[maxn]; struct N{ int to,next; N(int t=0,int n=0):to(t),next(n) {} }edge[maxn<<1]; void add(int x,int y){edge[++ct]=N(y,head[x]); head[x]=ct;} bool dfs(int x) { for(int i=head[x],u;i;i=edge[i].next) { if(vis[u=edge[i].to]!=ans) // if(!vis[u=edge[i].to])//TLE! { vis[u]=ans; if(!pre[u]||dfs(pre[u])) { pre[u]=x; return 1; } } } return 0; } int main() { scanf("%d",&n); for(int i=1,x,y;i<=n;i++) { scanf("%d%d",&x,&y); add(x,i); add(y,i); mx=max(mx,max(x,y)); } for(int i=1;i<=mx;i++) { // memset(vis,0,sizeof vis);//TLE! ans++; if(!dfs(i)) { printf("%d\n",ans-1); return 0; } } printf("%d",ans); return 0; }