解题思路:建立图,对图的每一个顶点进行遍历。每一次的遍历中如果能够遍历所有的顶点。则任意两个房间连通。这题我用的是深度搜索。本题要注意的是房间数N<=10000,如果用邻接矩阵解题,内存不够。我的解答用的是向量来建立邻接表,vector是动态分配内存的,用时再分配,解决内存不够的问题。用栈保存上一次的顶点。
例:输入
3 3
1 2
2 3
3 1
邻接表 row[1]->2
row[2]->3
row[3]->1
//邻接表的非递归深度遍历
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int num, line, b, visit[10001], N;
int main()
{
int line, i, a, b;
while (cin>>num>>line && (num||line))
{
vector <int>row[10001];
while (line--)
{
cin>>a>>b;
row[a].push_back(b);
}
for (i=1; i<=num; i++)
{
N=0;//N记录是否从i开始的每一条边都遍历了
memset(visit, 0, sizeof(visit));
int j, flag, n; //非递归深度优先遍历
stack <int> s;
s.push(i);
while (!s.empty())
{
flag = 0;
n = s.top();
if (!visit[n])
visit[n] = 1;
j = 0;
while (j<row[n].size())
{
if (!visit[row[n][j]]) //将下一个深度优先的顶点放入栈中
{
flag = 1;
N++;
s.push(row[n][j]);
break;
}
j++;
}
if (flag==0) // 一次while后没有入栈的量,原路返回,将原来的顶点取出
s.pop();
}
if (N!=num-1)
{
cout<<"No"<<endl;
break;
}
if (N==num-1 && num==i)
cout<<"Yes"<<endl;
}
}
return 0;
}
//邻接表的递归深度遍历
#include <iostream>
#include <vector>
using namespace std;
int num, line, b, visit[10001], N;
int DFS(int n, vector<int>row[])
{
int i;
visit[n] = 1;
for (i=0; i<row[n].size(); i++)
if (visit[row[n][i]]==0)
{
N++;
DFS(row[n][i],row);
}
return N;
}
int main()
{
int line, i, a, b;
while (cin>>num>>line && (num||line))
{
vector <int>row[10001];
while (line--)
{
cin>>a>>b;
row[a].push_back(b);
}
for (i=1; i<=num; i++)
{
memset(visit, 0, sizeof(visit));
N = 0;
N=DFS(i, row);
if (N!=num-1)
{
cout<<"No"<<endl;
break;
}
if (N==num-1 && num==i)
cout<<"Yes"<<endl;
}
}
return 0;
}