题目链接:UVa 208 - Firetruck
题意不太难,不过直接搜下去会超时,需要提前处理一下。
用bfs或者dfs等方法把与终点联通的点求出来,把这些点放进一个数组,接下来回溯时候只从这个数组里取点。
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAX_N = 21;
int n,a,b;
int map[MAX_N + 3][MAX_N + 3];
int num[MAX_N];
int _count,cnt,_case;
queue <int> q;
int vis[MAX_N + 3];
int flag[MAX_N + 3];
void bfs()
{
q.push(n);
vis[n] = 1;
num[cnt++] = n;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 1;i < MAX_N;i++)
{
if(!vis[i] && map[u][i])
{
vis[i] = 1;
num[cnt++] = i;
q.push(i);
}
}
}
}
void dfs(int _cnt,int b)
{
if(b == n)
{
for(int i = 0;i < _cnt;i++)
{
if(i == _cnt - 1)
cout << flag[i] << endl;
else
cout << flag[i] << " ";
}
_count++;
}
else
{
for(int i = 0;i < cnt;i++)
{
if(!vis[num[i]] && map[b][num[i]])
{
flag[_cnt] = num[i];
vis[num[i]] = 1;
dfs(_cnt + 1,num[i]);
vis[num[i]] = 0;
}
}
}
}
int main()
{
_case = 0;
while(cin >> n)
{
_count = 0;
cnt = 0;
memset(map,0,sizeof(map));
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
while(cin>>a>>b,a + b)
map[a][b] = map[b][a] = 1;
bfs();
memset(vis,0,sizeof(vis));
sort(num,num + cnt);
vis[1] = 1;
flag[0] = 1;
cout << "CASE " << ++_case << ":" << endl;
dfs(1,1);
cout << "There are "<< _count << " routes from the firestation to streetcorner " << n << "." << endl;
}
return 0;
}

1974

被折叠的 条评论
为什么被折叠?



