小明最近做了农场看守,他每天晚上的工作就是巡视农场并且保证没有人破坏农场。从谷仓出
发去巡视,并且最终回到谷仓。
小明视力不太好,其他农场守卫只需要对农场的每一条连接不同场地的路走一遍就可以发现是
不是有异常情况了。但是他很仔细和耐心,对农场的每一条连接不同场地的路需要走两遍,并
且这两遍必须是不同的方向,因为他觉得应该不会两次都忽略农场中的异常情况。
每两块地之间一定至少有一条路连接。现在的任务就是帮他制定巡视路径。
输入格式: 第一行输入两个整数 N(2≤N≤10000) 和 M(1≤M≤50000),表示农场一共有N 块
地 M 条边。第二到 M+1 行输入两个整数,表示对应的两块地之间有一条边。
输出格式: 输出 2M+1个数,一个数占一行,表示小明巡查路径上地的标号,1 号为谷仓,从
1 开始,以 1 结束。如果有多种答案,输出任意一种。
本题答案不唯一,符合要求的答案均正确
样例输入
4 5
1 2
1 4
2 3
2 4
3 4
样例输出
1
2
3
4
2
1
4
3
2
4
1
这道题的意思是有M座桥然后经过2M+1个岛屿把每座桥的两个方向都走一遍。如果用邻接矩阵来储存桥的信息的话。它其实就已经把每座桥的两个方向(从哪到哪)的数字设为了1。所以我们我们只需要把邻接矩阵里的每一个1都走一遍就行了。怎么走呢(因为必须是通过一个桥从一个岛到另一个岛,所以每次搜索到的当前行可行的列值将作为下一次搜索的行值如[1,4]这个就代表着从1号岛到4号岛,下一次再将4作为行值[4,?],再去搜索列值。直到把所有的“1”都一遍走完)
邻接矩阵法
#include <iostream>
#include <list>
using namespace std;
int n,m;
const int MAX=1000;
int a[MAX][MAX];
list<int> arr;
bool flag=0;
void dfs(int rol,int step)
{
if(flag==1)
return;
if(step==10)
{
while(!arr.empty())
{
cout<<arr.front()<<" ";
arr.pop_front();
}
flag=1;
return ;
}
else
{
for(int i=1;i<=n;i++)
{
if(a[rol][i]==1)
{
a[rol][i]=0;
arr.push_back(i);
dfs(i,step+1);
a[rol][i]=1;
arr.pop_back();
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
a[i][j]=0;
int x,y;
for(int i=0;i<m;i++)
{
cin>>x>>y;
a[x][y]=1;
a[y][x]=1;
}
arr.push_back(1);
dfs(1,0);
return 0;
}
邻接表法
但是通过邻接矩阵来储存信息需要的空间是n*n个的,但是储存的“1”值往往比这个值小的多。所以可以通过用邻接表来储存信息。方法和想法都是与邻接矩阵类似的。
#include <iostream>
#include <vector>
#include <list>
using namespace std;
const int MAX=10001;
vector<int> a[MAX];
list<int> arr;
bool flag=0;
void dfs(int rol,int step)
{
if(flag==1)
return;
if(step==10)
{
while(!arr.empty())
{
cout<<arr.front()<<" ";
arr.pop_front();
}
flag=1;
return;
}
else
{
while(!a[rol].empty())
{
if(flag==1)
return;
int temp=a[rol].back();
a[rol].pop_back();
arr.push_back(temp);
dfs(temp,step+1);
a[rol].push_back(temp);
arr.pop_back();
}
}
}
int main()
{
int n,m;
cin>>n>>m;
int x,y;
for(int i=0; i<m; i++)
{
cin>>x>>y;
a[x].push_back(y);
a[y].push_back(x);
}
arr.push_back(1);
dfs(1,0);
return 0;
}