显然题目是要找一条字典序最小的哈密尔顿环路。
根据题目的要求进行构图,并且将邻接矩阵排序(因为要最小字典序)。如果有答案,一定是从1开始,因此从1开始dfs。vis[u][st] 表示点u状态为st(st记录了到达u之前哪些点访问过)这个状态是否访问过。根据哈密尔顿环的性质显然每种状态只需要访问一次。因此时间复杂度为
O(n2n)
。
#include<bits/stdc++.h>
using namespace std;
bool vis[20][1<<20],use[20],G[20][20];
vector<int> adj[20];
string s[20];
int ans[20],n,finish;
bool dfs(int u, int d, int st)
{
ans[d]=u;
if(st==finish)
{
if(G[u][0]) return true;
else return false;
}
for(int v : adj[u])
{
if(!v) continue;
int nst=st|(1<<v);
if(use[v]||vis[v][nst]) continue;
vis[v][nst]=true;
use[v]=true;
if(dfs(v,d+1,nst)) return true;
use[v]=false;
}
return false;
}
int main()
{
cin>>n;
finish=(1<<n)-1;
for(int i=0;i<n;i++)
{
cin>>s[i];
for(int j=0;j<n;j++)
if(s[i][j]=='W') adj[i].push_back(j),G[i][j]=true;
else if(s[i][j]=='L') adj[j].push_back(i),G[j][i]=true;
}
for(int i=0;i<n;i++) sort(adj[i].begin(),adj[i].end());
use[0]=true;
vis[0][1]=true;
if(dfs(0,0,1))
{
for(int i=0;i<n;i++)
printf("%d%c",ans[i]+1,i+1==n?'\n':' ');
}
else puts("No Solution");
return 0;
}

本文介绍了一种寻找字典序最小的哈密尔顿环路的方法,通过构造邻接矩阵并使用深度优先搜索算法来解决团体程序设计天梯赛中的球队“食物链”问题。
&spm=1001.2101.3001.5002&articleId=69676878&d=1&t=3&u=ceb6e27c48214f06aaa9f4fbb0507055)
234

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



