hdu 5438 ponds

题目链接: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;
		}
	}	
}

猜你喜欢

转载自blog.csdn.net/DA_A_MAO/article/details/81562094
hdu
今日推荐