题意就是判断任意两点是否联通,因为是有向图,就要求任意两点之间至少有一条单向路,一开始没什么思路,在没有思路的时候暴力搜索就是最好的思路. 因为暴力出奇迹.
但还是先算一下时间复杂度.
搜索的话,就是对每一个点进行广搜,记录每一个点可以到达的点,这样的话 时间复杂度就为 N * M = 2e7 . 所以这是可以暴力的.
不过广搜的时候,发现的一个问题,因为一个点可以出现出队后在入队的情况.这样就会死循环.
这是就要开一个标记数组,记录当前队列中的入队情况,防止这样的情况发生.
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int MAXN = 2e3 + 10;
int n,m;
vector<int> G[MAXN];
int path[MAXN][MAXN];
bool tag[MAXN];
void f(int u)
{
queue<int> q;
memset(tag,0,sizeof(tag));
while(!q.empty()) q.pop();
q.push(u);
path[u][u] = 1;
tag[u] = 1;
while(!q.empty())
{
int temp = q.front();
q.pop();
int l = G[temp].size();
for(int i = 0;i <= l - 1;++i)
{
int v = G[temp][i];
if(!tag[v])
{
path[u][v] = 1;
q.push(v);
tag[v] = 1;
}
}
}
return ;
}
int main()
{
int T;
cin >> T;
int cnt = 1;
while(T--)
{
cout << "Case " << cnt++ << ": ";
cin >> n >> m;
memset(path,0,sizeof(path));
for(int i = 1;i <= MAXN - 1;++i)
G[i].clear();
for(int i = 1;i <= m;++i)
{
int a,b;
cin >> a >> b;
G[a].push_back(b);
}
for(int i = 1;i <= n;++i)
{
f(i);
}
// for(int i = 1;i <= n;++i)
// {
// for(int j = 1;j <= n;++j)
// {
// if(j == 1)
// cout << path[i][j];
// else
// cout << " " << path[i][j] << endl;
// }
// cout << endl;
// }
bool flag = 0;
for(int i = 1;i <= n - 1;++i)
{
for(int j = i + 1;j <= n;++j)
{
if(path[i][j] == 1 || path[j][i] == 1)
{
;
}
else
{
flag = 1;
cout << "The Burning Shadow consume us all" << endl;
break;
}
}
if(flag) break;
}
if(!flag)
cout << "Kalimdor is just ahead" << endl;
}
}
死循环的根本原因还是没有设计好状态,没有考虑清楚的划分,脑子中没有形成清楚的搜索顺序.
还有就是队列标记的使用.