/** 题目: uvalive 3231 Fair Share 公平分配问题 链接:https://vjudge.net/problem/UVALive-3231 题意:有m个任务,n个处理器,每个任务有两个候选处理器,只要其中一个运行,该任务就能执行。 不同任务的两个候选处理器,至少有一个不同。 求任务数最多的那个处理器所分配的任务数尽量少。 思路:二分+最大流 左边是任务,s->u,cap = 1。 如果任务u和u的候选处理器v,u->v, cap = 1. 右边是处理器,二分mi。所有处理器v,v->t, cap = mi; 求s-t最大流flow,如果flow等于任务数,那么可行解。找一个最小的mi即可。 */ #include<iostream> #include<cstring> #include<vector> #include<map> #include<cstdio> #include<sstream> #include<algorithm> #include<queue> using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; typedef long long LL; const int N = 11010;///n+m=1000+10000=11000; struct Edge{ int from, to, cap, flow; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} }; struct Dinic{ int n, m, s, t; vector<Edge> edges; vector<int> G[N]; bool vis[N]; int d[N]; int cur[N]; void init(int n) { this->n = n; for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS(){ memset(vis, 0, sizeof vis); queue<int> Q; Q.push(s); d[s] = 0; vis[s] = 1; while(!Q.empty()){ int x = Q.front(); Q.pop(); for(int i = 0; i < G[x].size(); i++){ Edge &e = edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow){ vis[e.to] = 1; d[e.to] = d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a){ if(x==t||a==0) return a; int flow = 0, f; for(int &i = cur[x]; i < G[x].size(); i++){ Edge& e = edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a==0) break; } } return flow; } int Maxflow(int s,int t){ this->s = s, this->t = t; int flow = 0; while(BFS()){ memset(cur, 0, sizeof cur); flow += DFS(s,INF); } return flow; } }; int main() { int T, n, m; cin>>T; while(T--) { scanf("%d%d",&n,&m); int s = 0, t = n+m+1; Dinic dinic, save; dinic.init(t); int u , v; for(int i = 1; i <= m; i++){ scanf("%d%d",&u,&v); dinic.AddEdge(s,i,1); dinic.AddEdge(i,u+m,1); dinic.AddEdge(i,v+m,1); } save = dinic; int lo = 0, hi = INF, mi, ans; while(lo<=hi){ mi = (lo+hi)/2; dinic = save; for(int i = 1; i <= n; i++){ dinic.AddEdge(i+m,t,mi); } int flow = dinic.Maxflow(s,t); if(flow==m){ ans = mi; hi = mi-1; }else { lo = mi+1; } } printf("%d ",ans); } return 0; }