hdu_3081

来源:互联网 发布:socat 端口转发 编辑:程序博客网 时间:2024/06/07 00:09
二分+最大流,处理关系的时候使用并查集会比较好,建图简单,忽略
#include <stdio.h>#include <string.h>#include <algorithm>#define MAXVERTEX 512#define INF 0x7fffffffusing namespace std;typedef struct $edge {int x, y;}Edge;Edge edge_arr[MAXVERTEX*MAXVERTEX];int used[MAXVERTEX][MAXVERTEX];int root[MAXVERTEX], residual[MAXVERTEX][MAXVERTEX], end_vertex;int pre[MAXVERTEX], cur[MAXVERTEX], dis[MAXVERTEX], gap[MAXVERTEX];int get_root(int x){if( x == root[x] )return x;return root[x] = get_root(root[x]);}void make_graph(int m, int arc, int vertex){int f, t;memset(residual, 0, sizeof(residual));for(int i = 1; i <= vertex; i ++)residual[end_vertex-1][i] = m;for(int i = vertex+1; i < end_vertex-1; i ++) residual[i][end_vertex] = m;for(int i = 0; i < arc; i ++) {f = edge_arr[i].x; t = edge_arr[i].y; residual[f][t] = 1;for(int j = 1; j <= vertex; j ++) {if( root[f] == root[j]) residual[j][t] = 1;}}}int i_sap(int source, int sink){int u(source), v, min_dist, max_flow(0), path_flow(INF);memset(dis, 0, sizeof(dis));memset(gap, 0, sizeof(gap));memset(cur, 0, sizeof(cur));gap[0] = sink; cur[source] = pre[source] = source;while( dis[source] < sink ) {loop:for(v = cur[u]; v <= sink; v ++) {if( !residual[u][v] || (dis[u] != dis[v]+1) )continue;pre[v] = u; path_flow = min(path_flow, residual[u][v]);cur[u] = v; u = v;if( v == sink ) {for(u = pre[u]; v != source; v = u, u = pre[u]) {residual[u][v] -= path_flow;  residual[v][u] += path_flow;}max_flow += path_flow; path_flow = INF;}goto loop;}min_dist = sink;for(v = 1; v <= sink; v ++) {if( residual[u][v] && (min_dist > dis[v]) ) {cur[u] = v; min_dist = dis[v];}}gap[dis[u]] --;if( !gap[dis[u]] )break;dis[u] = min_dist+1;gap[dis[u]] ++; u = pre[u];}//printf("max_flow = %d\n", max_flow);return max_flow;}int main(int argc, char const *argv[]){//freopen("test.in", "r", stdin);int cnt, vertex, arc, match, l, r, m, x, y, r_x, r_y, ans;scanf("%d", &cnt);while( cnt-- ) {scanf("%d %d %d", &vertex, &arc, &match);end_vertex = (vertex<<1)+2;for(int i = 0; i < arc; i ++) {scanf("%d %d", &edge_arr[i].x, &edge_arr[i].y);edge_arr[i].y += vertex;}for(int i = 0; i <= end_vertex; i ++)root[i] = i;for(int i = 0; i < match; i ++) {scanf("%d %d", &x, &y);r_x = get_root(x); r_y = get_root(y);if( r_x != r_y ) root[r_x] = r_y;}for(int i = 0; i <= end_vertex; i ++)root[i] = get_root(i);l = 1, r = vertex, ans = 0;while( l <= r ) {m = (l+r)>>1; make_graph(m, arc, vertex);if( m*vertex == i_sap(end_vertex-1, end_vertex) ){ans = m; l = m+1;}elser = m-1;}printf("%d\n", ans);}return 0;}


原创粉丝点击