传送门: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; }