以后多看多做英文题,看不懂也要看!
最小的启动次数 ,意思就是用最少得点覆盖所有的边
最小顶点覆盖=最大二分匹配数
#include<stdio.h> #include<string.h> const int NV = 1505; const int NE = 10000; struct MaxMatch { int n, size; int head[NV]; int aug[NV]; bool mark[NV]; struct Edge { int v, w, next; Edge () {} Edge (int V, int NEXT, int W = 0) : v(V), next(NEXT), w(W) {} }E[NE]; inline void init(int vx) { n = vx, size = 0; for (int i = 0; i <= n; i++) { head[i] = -1; } } inline void insert(int u, int v, int w = 0) { E[size] = Edge(v, head[u], w); head[u] = size++; } inline int Hungary(int n) { int match = 0; memset(aug, -1, sizeof(aug)); for (int i = 1; i <= n; i++) { if (aug[i] == -1) {//剪枝 memset(mark, false, sizeof(mark)); match += Find(i); } } return match; } inline bool Find(int u) { for (int i = head[u]; i != -1; i = E[i].next) { int v = E[i].v; if (mark[v]) continue; mark[v] = true; if (aug[v] == -1 || Find(aug[v])) { aug[v] = u, aug[u] = v; return true; } } return false; } }g; int main() { int k, m, n, a, b,c; while (scanf("%d", &n)&&n) { scanf("%d%d", &m, &k); g.init(m + n); while (k--) { scanf("%d%d%d", &c,&a,&b); // if(a&&b) 不加限制条件也可以过 g.insert(a, b + n); } printf("%d\n", g.Hungary(n)); } return 0; }