1 4 5 2 1 1 2 3 3 2 4 2 4 4 1 4 2 3
2
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 300; 18 struct arc { 19 int to,flow,next; 20 arc(int x = 0,int y = 0,int z = -1) { 21 to = x; 22 flow = y; 23 next = z; 24 } 25 }; 26 arc e[100000]; 27 bool g[maxn][maxn]; 28 int head[maxn],d[maxn],cur[maxn]; 29 int S,T,tot,n,m,f; 30 void add(int u,int v,int flow) { 31 e[tot] = arc(v,flow,head[u]); 32 head[u] = tot++; 33 e[tot] = arc(u,0,head[v]); 34 head[v] = tot++; 35 } 36 void Floyd() { 37 for(int k = 1; k <= n+n; ++k) { 38 for(int i = 1; i <= n+n; ++i) { 39 for(int j = 1; j <= n+n; ++j) { 40 if(i == j || i == k || j == k) continue; 41 if(!g[i][j]) g[i][j] = g[i][k]&&g[k][j]; 42 } 43 } 44 } 45 } 46 bool bfs() { 47 queue<int>q; 48 memset(d,-1,sizeof(d)); 49 d[S] = 1; 50 q.push(S); 51 while(!q.empty()) { 52 int u = q.front(); 53 q.pop(); 54 for(int i = head[u]; ~i; i = e[i].next) { 55 if(e[i].flow && d[e[i].to] == -1) { 56 d[e[i].to] = d[u] + 1; 57 q.push(e[i].to); 58 } 59 } 60 } 61 return d[T] > -1; 62 } 63 int dfs(int u,int low) { 64 if(u == T) return low; 65 int tmp = 0,a; 66 for(int &i = cur[u]; ~i; i = e[i].next) { 67 if(e[i].flow && d[e[i].to] == d[u] + 1 &&(a=dfs(e[i].to,min(e[i].flow,low)))) { 68 e[i].flow -= a; 69 e[i^1].flow += a; 70 low -= a; 71 tmp += a; 72 if(!low) break; 73 } 74 } 75 if(!tmp) d[u] = -1; 76 return tmp; 77 } 78 int dinic() { 79 int tmp = 0; 80 while(bfs()) { 81 memcpy(cur,head,sizeof(head)); 82 tmp += dfs(S,INF); 83 } 84 return tmp; 85 } 86 void build(int delta) { 87 memset(head,-1,sizeof(head)); 88 tot = 0; 89 for(int i = 1; i <= n; ++i) { 90 add(S,i,delta); 91 add(i+n,T,delta); 92 } 93 for(int i = 1; i <= n; ++i){ 94 for(int j = n+1; j <= n+n; ++j){ 95 if(g[i][j]) add(i,j,1); 96 } 97 } 98 } 99 int main() { 100 int cs,u,v; 101 scanf("%d",&cs); 102 while(cs--) { 103 scanf("%d %d %d",&n,&m,&f); 104 S = 0; 105 T = n<<1|1; 106 memset(g,false,sizeof(g)); 107 for(int i = 0; i < m; ++i) { 108 scanf("%d %d",&u,&v); 109 g[u][v+n] = true;//g[v+n][u] = true; 110 //居然是有向的。。。为什么呢? 111 } 112 for(int i = 0; i < f; ++i) { 113 scanf("%d %d",&u,&v); 114 g[u][v] = g[v][u] = true; 115 } 116 Floyd(); 117 int low = 0,high = n,ans = 0; 118 while(low <= high){ 119 int mid = (low + high) >>1; 120 build(mid); 121 int tmp = dinic(); 122 if(tmp == n*mid){ 123 ans = mid; 124 low = mid+1; 125 }else high = mid-1; 126 } 127 printf("%d\n",ans); 128 } 129 return 0; 130 }