#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
using namespace std;
int n,m,l,t;
struct node
{
int next,to;
double cap;
}edge[50001];
int size=1,head[501];
void putin(int from,int to,double cap)
{
size++;
edge[size].to=to;
edge[size].cap=cap;
edge[size].next=head[from];
head[from]=size;
}
void in(int from,int to,double cap)
{
putin(from,to,cap);
putin(to,from,0);
}
int dist[501],numbs[501];
void bfs(int src,int des)
{
int i;
memset(dist,0,sizeof(dist));
memset(numbs,0,sizeof(numbs));
queue<int>mem;
mem.push(des);
dist[des]=0;numbs[0]++;
while(!mem.empty())
{
int x=mem.front();mem.pop();
for(i=head[x];i!=-1;i=edge[i].next)
{
int y=edge[i].to;
if(edge[i].cap==0&&dist[y]==0&&y!=des)
{
dist[y]=dist[x]+1;
numbs[dist[y]]++;
mem.push(y);
}
}
}
return;
}
double dfs(int src,double flow,int des)
{
if(src==des)return flow;
int i,mindist=n+m+2;
double low=0;
for(i=head[src];i!=-1;i=edge[i].next)
{
int y=edge[i].to;
if(edge[i].cap)
{
if(dist[y]==dist[src]-1)
{
double t=dfs(y,min(flow-low,edge[i].cap),des);
edge[i].cap-=t;
edge[i^1].cap+=t;
low+=t;
if(dist[src]>=n+m+2)return low;
if(flow==low)break;
}
mindist=min(mindist,dist[y]+1);
}
}
if(!low)
{
if(!(--numbs[dist[src]]))dist[n+m+2]=n+m+2;
++numbs[dist[src]=mindist];
}
return low;
}
double ISAP(int src,int des)
{
double ans=0;
bfs(src,des);
while(dist[0]<n+m+2)ans+=dfs(src,2e8,des);
return ans;
}
int main()
{
int i,j;
scanf("%d",&t);
while(t--)
{
size=1;
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&l);
for(i=1;i<=n;i++)
{
double q;
scanf("%lf",&q);
in(0,i,log(q));
}
for(i=1;i<=m;i++)
{
double q;
scanf("%lf",&q);
in(n+i,n+m+1,log(q));
}
for(i=1;i<=l;i++)
{
int from,to;
scanf("%d%d",&from,&to);
in(from,n+to,100000000);
}
double maxflow=ISAP(0,n+m+1);
printf("%.4lf\n",exp(maxflow));
}
return 0;
}