bzoj1854: [Scoi2010]游戏
二分图的最大匹配。将每个武器的俩个属性与这个武器连边。枚举属性,无法匹配就输出。
基本概念:(口述非官方)
二分图:把一个图的顶点分为俩部分,每部分的每个点之间都没有边相连。
匹配:在二分图中,找出一些边,每个边都没有公共点。
最大匹配:最大的匹配。
完美匹配:每个点都用上的匹配,2*边数 = 点数。
其实二分图的最大匹配可以用最大流算法来解释。每个边容量为1。但效率不高。
匈牙利算法。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 1000000 + 10; const int maxm = 4000000 + 10; const int maxv = 10000 + 10; int n,eid; int h[maxv],to[maxm],next[maxm],v[maxm]; int p[maxn]; bool vis[maxv]; void add(int a,int b) { v[eid] = b; next[eid] = h[a]; h[a] = eid++; } bool find(int u) { if(vis[u]) return false; vis[u] = true; for(int i = h[u];~i; i = next[i]) { if(!p[v[i]] || find(p[v[i]])) { p[v[i]] = u; return true; } } return false; } int main() { scanf("%d",&n); memset(h,-1,sizeof(h)); for(int i = 1,a,b; i <= n; i++) { scanf("%d%d",&a,&b); add(a,i); add(b,i); } int res; for(res = 1; res <= 10000; res++) { memset(vis,0,sizeof(vis)); if(!find(res)) break; } printf("%d\n",res-1); return 0; }