#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cstdio>
#define maxn 10005
#define INF 0x3fffffff
#define ll __int64
using namespace std;
int du[maxn];//存储每个点的入度
int s[maxn]; //并查集根的存储
ll val[maxn];
vector<int> v[maxn];//存储边
queue<int> Q; //广搜使用的队列
int T,n,m;
void bfs(){//广搜度为1的点,将其相邻的点度减1
for(int i=1;i<=n;i++)
if(du[i]==1)Q.push(i);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=0;i<v[u].size();i++){
int x=v[u][i];
if(du[x]) du[x]--;
if(du[x]==1)
Q.push(x);
}
du[u]=0;
v[u].clear();
}
}
int Find(int num){
return s[num]<0?num:s[num]=Find(s[num]);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%I64d",&val[i]);
int x,y;
memset(v,0,sizeof(v));
memset(du,0,sizeof(du));
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
du[x]++;
du[y]++;
}
for(int i=1;i<=n;i++)
if(du[i]==1)
bfs();
memset(s,-1,sizeof(s));
//并查集合并每个集合
for(int i=1;i<=n;i++){
for(int j=0;j<v[i].size();j++){
y=v[i][j];
if(du[i]&&du[y]){
int xx=Find(i);
int yy=Find(y);
if(xx!=yy){
s[xx]+=s[yy];
s[yy]=xx;
}
}
}
}
ll ans=0;
//找出集合大小大于1并且是奇数集合中的所有元素
for(int i=1;i<=n;i++){
int t=-s[Find(i)];
if(t!=1&&t%2) ans+=val[i];
}
printf("%I64d\n",ans);
}
return 0;
}
HDU 5438 Ponds
最新推荐文章于 2019-01-26 21:11:30 发布
749

被折叠的 条评论
为什么被折叠?



