1 4 5 1 2 1 1 2 3 3 2 4 2 4 4 1 4 2 3
3
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 260; 4 struct arc{ 5 int to,flow,next; 6 arc(int x = 0,int y = 0,int z = 0){ 7 to = x; 8 flow = y; 9 next = z; 10 } 11 }e[1000010]; 12 int head[maxn*maxn],d[maxn*maxn],cur[maxn*maxn]; 13 int tot,n,m,k,S,T,uf[maxn]; 14 void add(int u,int v,int flow){ 15 e[tot] = arc(v,flow,head[u]); 16 head[u] = tot++; 17 e[tot] = arc(u,0,head[v]); 18 head[v] = tot++; 19 } 20 int Find(int x){ 21 if(x != uf[x]) uf[x] = Find(uf[x]); 22 return uf[x]; 23 } 24 bool bfs(){ 25 queue<int>q; 26 q.push(T); 27 memset(d,-1,sizeof d); 28 d[T] = 1; 29 while(!q.empty()){ 30 int u = q.front(); 31 q.pop(); 32 for(int i = head[u]; ~i; i = e[i].next){ 33 if(e[i^1].flow > 0 && d[e[i].to] == -1){ 34 d[e[i].to] = d[u] + 1; 35 q.push(e[i].to); 36 } 37 } 38 } 39 return d[S] > -1; 40 } 41 int dfs(int u,int low){ 42 if(u == T) return low; 43 int tmp = 0,a; 44 for(int &i = cur[u]; ~i; i = e[i].next){ 45 if(e[i].flow > 0 && d[e[i].to]+1== d[u]&&(a=dfs(e[i].to,min(e[i].flow,low)))){ 46 e[i].flow -= a; 47 low -= a; 48 e[i^1].flow += a; 49 tmp += a; 50 if(!low) break; 51 } 52 } 53 if(!tmp) d[u] = -1; 54 return tmp; 55 } 56 int dinic(){ 57 int ret = 0; 58 while(bfs()){ 59 memcpy(cur,head,sizeof head); 60 ret += dfs(S,INT_MAX); 61 } 62 return ret; 63 } 64 bool con[maxn][maxn]; 65 int g[maxn*maxn],b[maxn*maxn]; 66 void build(int mid){ 67 memset(head,-1,sizeof head); 68 tot = 0; 69 for(int i = 1; i <= n; ++i){ 70 add(i,i+n,k); 71 add(S,i,mid); 72 add(i+2*n,T,mid); 73 } 74 for(int i = 1; i <= n; ++i) 75 for(int j = 1; j <= n; ++j) 76 if(con[Find(i)][j]) add(i,j+2*n,1); 77 else add(i+n,j+2*n,1); 78 } 79 int main(){ 80 int kase,f,u,v; 81 scanf("%d",&kase); 82 while(kase--){ 83 scanf("%d%d%d%d",&n,&m,&k,&f); 84 S = 0; 85 T = 3*n + 1; 86 for(int i = 0; i < maxn; ++i) uf[i] = i; 87 for(int i = 0; i < m; ++i) 88 scanf("%d%d",g+i,b+i); 89 for(int i = 0; i < f; ++i){ 90 scanf("%d%d",&u,&v); 91 u = Find(u); 92 v = Find(v); 93 if(u != v) uf[u] = v; 94 } 95 memset(con,false,sizeof con); 96 for(int i = 0; i < m; ++i) 97 con[Find(g[i])][b[i]] = true; 98 int low = 0,high = n,ret = 0; 99 while(low <= high){ 100 int mid = (low + high)>>1; 101 build(mid); 102 if(dinic() == n*mid){ 103 ret = mid; 104 low = mid+1; 105 }else high = mid - 1; 106 } 107 printf("%d\n",ret); 108 } 109 return 0; 110 }