无向图拓扑排序 和有向图拓扑在一些小细节上有些区别 可能会出现度数为负数的情况 最稳妥的方法就是在每个点拓扑入队列时标记 这样才能保证所有度为0或1的点都被删掉了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
const int maxm=1e5+10;
struct node
{
int v,next;
};
queue <int> que;
node edge[2*maxm];
ll val[maxn];
ll sum;
int first[maxn],degree[maxn],book[maxn];
int n,m,num;
void init()
{
while(!que.empty()) que.pop();
memset(first,-1,sizeof(first));
memset(degree,0,sizeof(degree));
memset(book,0,sizeof(book));
num=0;
}
void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
}
void toposort()
{
int i,u,v;
for(i=1;i<=n;i++){
if(degree[i]==1){
que.push(i);
book[i]=1;
}
}
while(!que.empty()){
u=que.front();
que.pop();
for(i=first[u];i!=-1;i=edge[i].next){
v=edge[i].v;
if(!book[v]){
degree[v]--;
if(degree[v]==1){
que.push(v);
book[v]=1;
}
}
}
}
}
void dfs(int cur)
{
int i,v;
num++,sum+=val[cur];
for(i=first[cur];i!=-1;i=edge[i].next){
v=edge[i].v;
if(!book[v]){
book[v]=1;
dfs(v);
}
}
}
int main()
{
ll ans;
int t,i,u,v;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%lld",&val[i]);
}
init();
while(m--){
scanf("%d%d",&u,&v);
addedge(u,v),addedge(v,u);
degree[u]++,degree[v]++;
}
toposort();
ans=0;
for(i=1;i<=n;i++){
if(!book[i]){
num=0,sum=0;
book[i]=1;
dfs(i);
if(num>1&&num%2) ans+=sum;
}
}
printf("%lld\n",ans);
}
return 0;
}