首先拓扑排序可以去掉度小于2的,剩下的只会是环
其次注意题目说的是连通,所以可能有很多个环相连的情况,所以这时便要判断这一个连通分量里是否有奇数个点
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+100;
vector<int>G[maxn];
int vis[maxn];
int degree[maxn];
ll sum1;
int num[maxn];
int n,m;
int count_;
void init(int n){
for(int i=1;i<=n;i++)
G[i].clear();
memset(vis,0,sizeof(vis));
memset(degree,0,sizeof(degree));
}
void topcode(){
queue<int>Q;
for(int i=1;i<=n;i++){
if(degree[i]<=1){
vis[i]=1;
Q.push(i);
}
}
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!vis[v]){
degree[v]--;
if(degree[v]<=1){
vis[v]=1;
Q.push(v);
}
}
}
}
}
void dfs(int u){
vis[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(vis[v]==0){
sum1+=num[v];
count_++;
dfs(v);
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init(n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
int u,v;
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
degree[u]++;
degree[v]++;
}
topcode();
ll sum=0;
for(int i=1;i<=n;i++){
if(vis[i]==0){
sum1=num[i];
count_=1;
dfs(i);
if(count_&1)
sum+=sum1;
}
}
printf("%I64d\n",sum);
}
return 0;
}