您的位置:首页 > 其它

【dfs && 剪枝】PTA L3-015. 球队“食物链”(30分)

2018-03-18 13:56 405 查看
Step 1 Problem:

给你n个点 和 一个n*n的矩阵,第i行第j列为‘L’,代表j点可以到达i点;为‘W’,代表i点可以到达j点。输出字典序最小的哈密顿回路路径。

Step 2 Involving algorithms:

dfs搜索

Step 3 Ideas:

如果有回路,那么无论从哪个点为起点搜索都能搜索到回路,既然我们要求字典序最小,所以从1点开始搜索。

直接搜索会超时。

加入剪枝如下:

我们没有搜索到的点,如果都不能回到起点,那么没有搜索的点就没有搜索的意义。

Step 4 Code:

#include<bits/stdc++.h>
using namespace std;
const int N = 25;
bool Map

;
int path
, top, flag, n;
int vis
, vv
;
void dfs(int u)
{
path[top++] = u;
if(top == n && Map[u][1])
{
flag = 1; return ;
}
int i;
for(i = 1; i <= n; i++)//剪枝判断没有搜索过的点,能不能回到起点
{
if(!vis[i] && Map[i][1]) break;
}
if(i > n) {
return ;
}
for(i = 1; i <= n; i++)
{
if(!vis[i] && Map[u][i])
{
vis[i] = 1;
dfs(i);
if(flag) return;
top--;
vis[i] = 0;
}
}
}
int main()
{
scanf("%d", &n);
memset(Map, 0, sizeof(Map));
char s[100];
for(int i = 1; i <= n; i++)
{
scanf("%s", s+1);
for(int j = 1; j <= n; j++)
{
if(s[j] == 'L') Map[j][i] = 1;
if(s[j] == 'W') Map[i][j] = 1;
}
}
memset(vis, 0, sizeof(vis));
memset(vv, 0, sizeof(vv));
top = 0, flag = 0;
vis[1] = 1;
dfs(1);
if(flag) {
for(int i = 0; i < top; i++)
{
if(i) printf(" ");
printf("%d", path[i]);
}
printf("\n");
} else {
printf("No Solution\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: