SDUT 2604 第四届山东省ACM省赛 Thrall’s Dream(DFS或BFS)

传送门:SDUT 2604



题目大意:

给你一个有向图,问图中是否任意两点之间都存在路径可达。



思路:

我们可以先求出对于每个点,它可以到达的点有哪些。用数组 can[i][j] 保存点 i 到 j 是否可达。然后对于两个点 i、j 是否 i 不可到达 j 同时 j 也不可到达 i。


网上好多代码都是用 BFS写的,感觉没必要……DFS完全可以实现,并且代码更短,效率也差不多。既然是求每个点可达的点,我们只需要在 DFS的过程中记录当前 DFS的根节点就可以了。



代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
using namespace std;

int n,m,vis[2010],can[2010][2010];
vector<int> mp[2010];

void dfs(int u,int root)
{ //参数:当前节点,当前dfs 的根节点 
	int i,v;
	vis[u]=1;
	for(i=0;i<mp[u].size();i++)
	{
		v=mp[u][i];
		if(!vis[v]) 
		{			
			can[root][v]=1; //根节点可以到达 v 
			dfs(v,root);	
		}		
	}
}

int main()
{
	int i,j,t,u,v,f,cas;	
	scanf("%d",&t);
	cas=1;
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(i=0;i<=n;i++) mp[i].clear();
		for(i=0;i<m;i++)
		{
			scanf("%d%d",&u,&v);
			mp[u].push_back(v);
		}
		memset(can,0,sizeof(can));
		for(i=1;i<=n;i++)
		{
			memset(vis,0,sizeof(vis)); //未访问过			
			dfs(i,i);
		}
		f=1;
		for(i=1;i<=n;i++)
			for(j=i+1;j<=n;j++)
				if(!can[i][j]&&!can[j][i])
				{ //是否存在两点之间互不可达 
					f=0;					
					break;
				}
		if(!f) printf("Case %d: The Burning Shadow consume us all\n",cas++);
		else printf("Case %d: Kalimdor is just ahead\n",cas++);		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zuzhiang/article/details/80022905