1 //n件物品,m种关系,(有关系的2个不能在同一组)
2 //把所有物品分为2组,希望最后2组的差值尽可能小,输出较大者
3 /*
4 二分图涂色+可行性(01)背包
5 dp[i] =1表示 最后差值为i可行
6 建图后,对于每个连通分量记录差值,来求所有的可行
7 */
8 #include<bits/stdc++.h>
9 using namespace std;
10 int t,n,m;
11 #define N 250
12 #define M 102000
13 int a[N],head[N],sum;
14 int cnt,vis[N];
15 int dp[M],dp1[M];
16 int sum1=0,sum2=0;
17 void init(){
18 cnt = 0;
19 for(int i =0;i<N;i++) {
20 head[i] = -1;
21 vis[i] =0;//多组输入
22 }
23 }
24 struct Node{
25 int u,v,nex;
26 }e[N*2];
27 void add(int u,int v)
28 {
29 e[cnt].u=u;e[cnt].v=v;
30 e[cnt].nex=head[u];head[u]=cnt++;
31 }
32 void dfs(int x,int rt){
33 vis[x] = 1;
34 if(rt==0)
35 sum1+=a[x];
36 else{
37 sum2+=a[x];
38 }
39 for(int i =head[x];i!=-1;i=e[i].nex){
40 int v = e[i].v;
41 if(!vis[v])
42 dfs(v,rt^1);//0^1=1,1^1=0
43 }
44 }
45 int main()
46 {
47 scanf("%d",&t);
48 while(t--)
49 {
50 init();
51 scanf("%d%d",&n,&m);
52 int x,y;
53 sum =0;
54 for(int i =1;i<=n;i++)
55 {
56 scanf("%d",&a[i]);
57 sum+=a[i]/100;
58 a[i]/=100;//题目说明都是100的倍数
59 }
60 for(int i =0;i<m;i++) {
61 scanf("%d%d",&x,&y);
62 add(x,y);add(y,x);//无向图
63 }
64
65 int num;
66 for(int i =0;i<=sum;i++) dp[i] = 0;
67 dp[0] = 1;//dp[0]一定先设为1,来引入第一个差值
68 for(int i =1;i<=n;i++) {
69 if(!vis[i]){
70 sum1=0,sum2=0;
71 dfs(i,0);
72 num = abs(sum1-sum2);
73 //printf("%d %d %d\n",sum1,sum2,num);
74 for(int j=sum;j>=0;j--){
75 if(dp[j]){
76 //如 :0,j. 0 ,num 或者 j,0.0,num
77 if(abs(j+num)<=sum) dp1[abs(j+num)] =1;
78 dp1[abs(j-num)] =1;
79 }
80 }
81 for(int j =sum;j>=0;j--){
82 dp[j] = dp1[j],dp1[j] = 0;
83 }
84 }
85 }
86 //一定需要2个dp 数组,利用dp1一直更新到所有的物品都取完
87 for(int i =0;i<=sum;i++) {
88 if(dp[i]){
89
90 printf("%d\n",(sum+i)/2*100);
91 break;
92 }
93 }
94 }
95 return 0;
96 }