紫书习题 7-1 UVa 208 (爆搜加剪枝)

来源:互联网 发布:dkms linux 编辑:程序博客网 时间:2024/04/26 17:06

题意:构造出一张图,给出一个点,字典序输出所有从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;}
0 0