二分图最大权匹配 、 最小权匹配 模板

 KM 算法,详细资料见上一篇,此处只贴模板

 

#include #include #include #include using namespace std; int max(int a,int b) {return a

 

上面模板不好,会超时,关键是没有处理slack

 

#include using namespace std; #define maxn 502 #define INF 0xfffffff int sx[maxn], sy[maxn], mat[maxn][maxn]; int x[maxn], y[maxn], link[maxn]; int N, M, slack; int DFS(int t) { int i, tmp; sx[t] = 1; for (i = 0; i < M; i++) { if (!sy[i]) { tmp = x[t] + y[i] - mat[t][i]; if (tmp == 0) { sy[i] = 1; if (link[i] == -1 || DFS(link[i])) { link[i] = t; return 1; } } else if (tmp < slack) slack = tmp; } } return 0; } void KM() { int i, j; for (i = 0; i < N; i++) { x[i] = 0; for (j = 0; j < M; j++) { if (mat[i][j] > x[i]) x[i] = mat[i][j]; } } for (j = 0; j < M; j++) { y[j] = 0; } memset(link, -1, sizeof(link)); for (i = 0; i < N; i++) { while (1) { memset(sx, 0, sizeof(sx)); memset(sy, 0, sizeof(sy)); slack = INF; if (DFS(i)) break; for (j = 0; j < N; j++) { if (sx[j]) x[j] -= slack; } for (j = 0; j < M; j++) { if (sy[j]) y[j] += slack; } } } } int main(){ int i,j,a,b,c,t,ans,E; int cnt = 1; while (scanf("%d%d%d", &N, &M, &E) != EOF) { for (i = 0; i < N; i++) for (j = 0; j < M; j++) mat[i][j] = -INF; if (E == 0) { printf("Case %d: ", cnt++); puts("-1"); continue; } for(i=0;i= 0 && mat[t][i] != -INF) { count ++; ans += mat[t][i]; } } printf("%d/n", ans); } return 0; }

你可能感兴趣的:(二分图最大权匹配 、 最小权匹配 模板)