题意:m个任务n个处理器,一个任务只能在可供运行的两个机器中的其中一个上运行,问怎样分配使得任务最多的机器尽量少
思路:把任务和可以选择的机器连边,容量为1,建立源点汇点s, t,s到每个任务的容量为1,对于机器到汇点的容量二分答案
思路:把任务和可以选择的机器连边,容量为1,建立源点汇点s, t,s到每个任务的容量为1,对于机器到汇点的容量二分答案
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
const int maxn = 2 * 1e4 + 10;
const int INF = 1e9;
using namespace std;
struct P {
int to, cap, rev;
P() {}
P(int t, int c, int r) : to(t), cap(c), rev(r) {}
};
int n, m, T, s, t;
int lv[maxn], it[maxn];
vector<P> G[maxn];
map<int, int> cap[maxn];
void init() {
for(int i = 0; i < maxn; i++) {
G[i].clear();
cap[i].clear();
}
}
void add(int from, int to, int c) {
G[from].push_back(P(to, c, G[to].size()));
G[to].push_back(P(from, 0, G[from].size() - 1));
cap[from][to] = c;
}
bool bfs() {
memset(lv, -1, sizeof(lv));
queue<int> q; q.push(s);
lv[s] = 0;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i].to;
if(lv[v] < 0 && G[u][i].cap > 0) {
lv[v] = lv[u] + 1;
q.push(v);
}
}
}
return lv[t] != -1;
}
int dfs(int v, int t, int f) {
if(v == t) return f;
for(int &i = it[v]; i < G[v].size(); i++) {
P &e = G[v][i];
if(e.cap > 0 && lv[e.to] > lv[v]) {
int d = dfs(e.to, t, min(e.cap, f));
if(!d) continue;
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
return 0;
}
int maxflow() {
int f = 0;
while(1) {
if(!bfs()) return f;
memset(it, 0, sizeof(it));
int fl;
while((fl = dfs(s, t, INF)) > 0) f += fl;
}
}
int low() {
int l = 0, r = INF;
while(l < r) {
int mid = (l + r) >> 1;
for(int i = 1; i <= n; i++) cap[i][t] = mid;
for(int i = 0; i < maxn; i++) {
for(int j = 0; j < G[i].size(); j++) {
int to = G[i][j].to;
G[i][j].cap = cap[i][to];
}
}
int maxc = maxflow();
if(maxc == m) r = mid;
else l = mid + 1;
}
return r;
}
int main() {
scanf("%d", &T);
while(T--) {
init();
scanf("%d %d", &n, &m);
s = 0; t = n + m + 1;
for(int i = 1; i <= m; i++) {
int t1, t2, f = n + i;
scanf("%d %d", &t1, &t2);
add(f, t1, 1);
add(f, t2, 1);
add(s, f, 1);
}
for(int i = 1; i <= n; i++) {
add(i, t, 0);
}
printf("%d\n", low());
}
return 0;
}