CCF-csp 201709-4 通信网络(spfa) 题解

    第一下学期了,学院都在备战ccf-csp考试,所以就去刷了往年的真题,水平有限,可能解法不好,敬请见谅!

我刚好在学习图论的知识,就找了这题先做,感觉凭借着莽夫的勇气,我竟然一次就满分了,惊讶;

下面是思路:
    

1、用spfa求出所以点互相能否到达对方;

 
2、两重循环处理,使一个方向能到的,另一个方向也能
到; 
3、然后就是输出答案了;
废话不多说,贴上代码:

   

//100分 
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
vector<pair<int,int> >E[1005];//习惯用stl 
int d[1005][1005];//保存下每个点到另一个点是否通行; 
bool v[1005];
void init()//初始化 
{
	memset(d,inf,sizeof(d));
	return ;
}
queue<int>q;
int main()
{
	int n,m;
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		E[a].push_back(make_pair(b,0));
	}
	for(int i=1;i<=n;i++)// 用spfa求出dis数组 
	{
		memset(v,0,sizeof(v));
		while(!q.empty())q.pop();
		q.push(i);
		d[i][i]=0;
		v[i]=1;
		while(!q.empty())
		{
			int now=q.front();
			q.pop();
			v[now]=0;
			for(int j=0;j<E[now].size();j++)
			{
				int vv=E[now][j].first;
				if(d[i][vv]>d[i][now]+E[now][j].second)
				{
					d[i][vv]=d[i][now]+E[now][j].second;
					if(!v[vv]){
						q.push(vv);
						v[vv]=1;
					}
				}
			}
		}
	}
	int sum=0;
	for(int i=1;i<=n;i++)//循环一遍,把能传递信息的反向也行,但是不能一开始就用无向边; 
	for(int j=1;j<=n;j++)
	if(d[i][j]==0)d[j][i]=0;
	for(int i=1;i<=n;i++)//然后就是依次搜索能全部到达的 
	{
		int flag=0;
		for(int j=1;j<=n;j++)
		{
			if(d[i][j]==inf){
				flag=1;
				break;
			}
		}
		if(!flag)sum++;
	}
	cout<<sum<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/79661970