当前位置: 代码迷 >> 综合 >> POJ 2112 二分图多重匹配+二分+floyd
  详细解决方案

POJ 2112 二分图多重匹配+二分+floyd

热度:26   发布时间:2024-01-13 17:55:45.0

题目意思不在赘述

二分图多重匹配一般都可以用网络流来做,只不过网络流的代码太长。

具体看代码把


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <vector>
#define MAXN 250
#define MAXM 100005
#define INF 1000000007
#define eps 1e-11
#define lch(x) x<<1
#define rch(x) x<<1|1
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
using namespace std;
int d[MAXN][MAXN];
int K, C, M;
vector<int>g[MAXN];
int match[MAXN][MAXN];
int cnt[MAXN];
bool mark[MAXN];
void floyd(int n)
{for(int k = 1; k <= n; k++)for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)if(d[i][k] + d[k][j] < d[i][j])d[i][j] = d[i][k] + d[k][j];
}
int dfs(int u)
{int size = g[u].size();for(int i = 0; i < size; i++){int v = g[u][i];if(mark[v]) continue;mark[v] = 1;if(cnt[v] < M)  //M代表的是每个机器的容量,match存储匹配结果,cnt数组则是存每台机器已经匹配的数量{match[v][cnt[v]++] = u;return 1;}for(int j = 0; j < cnt[v]; j++)if(dfs(match[v][j])){match[v][j] = u;return 1;}}return 0;
}
int main()
{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[i][j]);if(i != j && d[i][j] == 0) d[i][j] = INF;}floyd(K + C);int low = 0, high = INF;int ans = INF;while(low <= high){int mid = (low + high) >> 1;for(int i = 0; i < MAXN; i++) g[i].clear();memset(match, 0, sizeof(match));memset(cnt, 0, sizeof(cnt));for(int i = K + 1; i <= K + C; i++)for(int j = 1; j <= K; j++)if(d[i][j] <= mid)g[i].push_back(j);int num = 0;for(int i = K + 1; i <= K + C; i++){memset(mark, 0, sizeof(mark));num += dfs(i);}if(num == C){high = mid - 1;ans = mid;}else low = mid + 1;}printf("%d\n", ans);return 0;
}