题目链接:https://vjudge.net/problem/241635/origin
题目其实并不难,只要你不把它做成有向图的强连通就不难。
先拓扑排序,尽可能的删掉所有度唯一的点,再bfs或者是说再求无向图的强联通的奇数分量。
其实你要把它看成有向图的强连通求解却不拓扑排序(这样的情况下你只能通过跳过含1个点的联通分量来求解),有个问题无法解决,就是 一个点连着两个不为点的强连通分量,这个点是单个联通分量你却不能跳过。
当然拓扑完后 bfs部分你也可以用并查集的思想处理。
AC code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int M=10e4;
int degree[M];
int value[M];
bool divs[M];
vector <int> ve[M];
int n,m;
queue <int> q;
long long ans,sum;
int quantity;
void init()
{
int a,b;
for(int i=1;i<=n;++i)
scanf("%d",&value[i]),ve[i].erase(ve[i].begin(),ve[i].end());
for(int i=1;i<=m;++i)
{
scanf("%d%d",&a,&b);
ve[a].push_back(b);
ve[b].push_back(a);
degree[a]++;
degree[b]++;
}
}
void toupu()
{
int t,u;
for(int i=1;i<=n;++i)
if(degree[i]==1) q.push(i);
while(!q.empty())
{
t=q.front();
q.pop();
degree[t]--;
for(int i=0;i<ve[t].size();++i)
{
u=ve[t][i];
degree[u]--;
if(degree[u]==1)
q.push(u);
}
}
}
void bfs(int k)
{
sum+=value[k];
quantity++;
divs[k]=1;
int u;
for(int i=0;i<ve[k].size();++i)
{
u=ve[k][i];
if(degree[u]>0&&!divs[u]) bfs(u);//degree[u]不能是等于零,因为只有两个点的联通分量中每个点的度都会变成负数。
}
}
int main()
{
int T;
while(cin>>T)
{
while(T--)
{
cin>>n>>m;
memset(degree,0,sizeof(degree));
memset(divs,0,sizeof(divs));
init();
toupu();
ans=0;
for(int i=1;i<=n;++i)
{
if(degree[i]>0&&!divs[i])
{
sum=0;
quantity=0;
bfs(i);
if(quantity&1)ans+=sum;
}
}
cout<<ans<<endl;
}
}
}