Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 3151 | Accepted: 1260 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
2 3 2 0 3 2 1 1 3 0 3 2 0 2 3 0 1 0 1 2 1 0 2 1 0 0 2 0
Sample Output
2
Source
/* 一般二分图匹配中,在一个匹配中,二分图中的 X 部与 Y 部中的点是一对一的。二分图多重匹配中,X 部中的点可以匹配多个 Y 部中的点, Y 部中的点最多只能匹配一个 X 部中的点 FLOYD求每对顶点间的最短路径 + 多重匈牙利算法 + 二分 */ #include <iostream> #define MAX_C 250 #define MAX_K 50 #define MAX_M 20 #define MAX_N 250 #define MAX_VAL 99999999 #define minv(a, b) ((a) <= (b) ? (a) : (b)) int dist[MAX_N][MAX_N][2]; int pre[MAX_K][MAX_M]; int k, c, m; bool v[MAX_K]; //初始化 void init() { int d; scanf("%d%d%d", &k, &c, &m); for(int i = 1; i <= k + c; i++) { for(int j = 1; j <= k + c; j++) { scanf("%d", &d); if(d == 0) dist[i][j][0] = MAX_VAL; else dist[i][j][0] = d; } } } //求每对顶点间的最短路径 void floyd() { int cp, lp = 0; for(int kp = 1; kp <= k + c; kp++) { cp = 1 - lp; for(int i = 1; i <= k + c; i++) { for(int j = 1; j <= k + c; j++) dist[i][j][cp] = minv(dist[i][j][lp], dist[i][kp][lp] + dist[kp][j][lp]); } lp = cp; } } //判断当前定点可不可以找到一条增广路径 bool canGo(int cid, int maxDist) { for(int i = 1; i <= k; i++) { if(dist[cid][i][(c + k) % 2] > maxDist) continue; if(v[i]) continue; v[i] = true; int num = pre[i][0]; if(num < m) { pre[i][++pre[i][0]] = cid; return true; } else if(num == m) { for(int j = 1; j <= pre[i][0]; j++) { if(canGo(pre[i][j], maxDist)) { pre[i][j] = cid; return true; } } } } return false; } //检查最大距离为maxDist是否可行 bool check(int maxDist) { memset(pre, 0, sizeof(pre)); int total = 0; for(int i = k + 1; i <= k + c; i++) { memset(v, 0, sizeof(v)); if(canGo(i, maxDist)) total++; } if(total == c) return true; else return false; } //二分 int partition() { int l = 0, r = 55000, m; while(l <= r) { m = (l + r) / 2; if(check(m)) r = m - 1; else l = m + 1; } return l; } int main() { init(); floyd(); printf("%d/n", partition()); return 0; }