团体程序设计天梯赛 L3-015 球队“食物链” (30分)(DFS + 剪枝)

题目链接:

L3-015 球队“食物链” (30分)

思路:

题意即给出的所有队能否连成环;
因为需要字典序小,我们优先遍历编号小的即可;
理所当然第一支队应该是1,我们在遍历的过程中,如果发现所有打败第一支队伍的队伍都已经被遍历过,则直接return

代码:

#include<bits/stdc++.h>

using namespace std;

const int maxn = 23;
int n, nex[maxn], cnt;
vector<int> G[maxn], t;
void dfs(int u, int ans) {
	for(int & x : t) if(!nex[x]) goto here;
	return; here:
	for(int & x : G[u]) {
		if(!nex[x] && x != 1) nex[u] = x, dfs(x, ans + 1);
		else if(ans == n && x == 1) {
			cout << 1;
			for(int i = nex[1]; i ; i = nex[i]) cout << ' ' << i;
			exit(0);
		}
	}
	nex[u] = 0;
}

int main() {
#ifdef MyTest
	freopen("Sakura.txt", "r", stdin);
#endif
	cin >> n;
	for(int i = 1; i <= n; i++)
	for(int j = 1; j <= n; j++) {
		char c;
		cin >> c;
		if(c == 'W') G[i].push_back(j);
		else if(c == 'L') G[j].push_back(i);
	}
	for(int i = 1; i <= n; i++) { 
		sort(G[i].begin(), G[i].end());
		G[i].resize(unique(G[i].begin(), G[i].end()) - G[i].begin());
		for(int & x : G[i]) if(x == 1) t.push_back(i);
	}
	dfs(1, 1); 
	puts("No Solution");
	return 0;
}
原文地址:https://www.cnblogs.com/yuhan-blog/p/12308628.html