题意:构造出一张图,给出一个点,字典序输出所有从1到该点的路径。
解题方法:裸搜会超时的题目,其实题目的数据特地设计得让图稠密但起点和终点却不相连,所以直接搜索过去会超时。只要判断下起点和终点能不能相连就行了,可以用并查集也可以用floyd算法,这样就能过了。还有一种就是我们可以先将所有与目标点联通的点存于一个数组中,仅在这个数组中查找,就省去很多无谓的查找时间。
代码如下: (用Floyd写的)
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int maze[30][30], dis[30][30];
bool vis[30];
int ans[30];
int dest, sum, cur_max_v;
void getmax(int &x, int y)
{
if(y > x) x = y;
}
void dfs(int u, int cnt)
{
if(u == dest)
{
printf("1");
for(int i = 1; i < cnt - 1; i++)
{
printf(" %d", ans[i]);
}
printf(" %d\n", dest);
sum++;
return ;
}
for(int i = 1; i <= cur_max_v; i++)
{
if(!vis[i] && maze[u][i] == 1 && dis[dest][i] != inf)
{
ans[cnt] = i;
vis[i] = 1;
dfs(i, cnt + 1);
vis[i] = 0;
}
}
}
int main()
{
int ks = 0;
while(scanf("%d", &dest) != EOF)
{
int x, y;
cur_max_v = 0;
for(int i = 1; i <= 20; i++)
{
for(int j = 1; j <= 20; j++)
{
dis[i][j] = inf;
}
}
memset(maze, 0, sizeof(maze));
memset(ans, 0, sizeof(ans));
memset(vis, false, sizeof(vis));
while(scanf("%d%d", &x, &y))
{
if(x == 0 && y == 0) break;
else
{
maze[x][y] = 1;
maze[y][x] = 1;
dis[x][y] = 1;
dis[y][x] = 1;
getmax(cur_max_v, x);
getmax(cur_max_v, y);
}
}
for(int i = 1; i <= cur_max_v; i++)
{
for(int j = 1; j <= cur_max_v; j++)
{
for(int k = 1; k <= cur_max_v; k++)
{
if(dis[j][k] > dis[j][i] + dis[i][k])
{
dis[j][k] = dis[j][i] + dis[i][k];
}
}
}
}
sum = 0;
vis[1] = 1;
printf("CASE %d:\n", ++ks);
dfs(1, 1);
printf("There are %d routes from the firestation to streetcorner %d.\n", sum, dest);
}
return 0;
}