Gym100851K King's Inspection(哈密尔顿回路)

Description

给你一张 n n n 个点 m m m 条边的有向图,求这张图 1 → 1 1 \to 1 11 的汉密尔顿回路。

1 ≤ n ≤ 1 0 5 , 1 ≤ m ≤ n + 20 1 \leq n\leq 10^5, 1 \leq m \leq n + 20 1n105,1mn+20

Solution

哈密尔顿回路是一个 NP 完全问题,复杂度是指数级的,但是 1 ≤ m ≤ n + 20 1 \leq m \leq n + 20 1mn+20,这代表图中有许多的出度为 1 1 1 的点,出度为 1 1 1 的点是不用跑的,所以将出度为 1 1 1 的点在图中标记为已经访问。那么坏的情况是每个点的出度为 2 2 2,图中有许多三角形拼接起来,那么最多有 20 20 20 个这样的点, 2 20 2^{20} 220 也不慌。
在这里插入图片描述

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
inline int read() {
	int x = 0, f = 0; char ch = 0;
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}
struct edge{
    int to, nxt;
}e[N];
int head[N], tot;
void addedge(int x, int y){
    e[++tot].to = y, e[tot].nxt = head[x], head[x] = tot;
}
int n, m, deg[N], vis[N], mark[N], nxt[N];
vector <int> cur;
bool check() {
	memset(mark, 0, sizeof(mark));
	for (int i = 1, x = 1; i <= n; i++, x = nxt[x]) {
		if (mark[x]) return 0;
		mark[x] = 1;
	}
	return 1;
}
void dfs(int t){
    if (t == cur.size()){
    	if (check()) {
    		for (int i = 1, x = 1; i <= n; i++, x = nxt[x]) printf("%d ", x);
   			puts("1"); exit(0);
    	}
   		return ;
    }
    int x = cur[t];
    for (int i = head[x]; i; i = e[i].nxt) {
    	int y = e[i].to;
    	if (!vis[y]) {
    		nxt[x] = y;
    		vis[y] = 1; 
			dfs(t + 1); 
			vis[y] = 0;
    	}
    }
}
int main() {
	//freopen("king.in", "r", stdin);
	//freopen("king.out", "w", stdout);
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();
		addedge(x, y); deg[x]++;
	}
	for (int i = 1; i <= n; i++) {
		if (deg[i] >= 2) cur.push_back(i);
		else if (deg[i] == 0) {
			puts("There is no route, Karl!"); 
			return 0;
		} else {
			if (vis[e[head[i]].to]) { 
				puts("There is no route, Karl!");
				return 0;
			}
			vis[e[head[i]].to] = 1;
		}
		nxt[i] = e[head[i]].to;
	}
	dfs(0);
	puts("There is no route, Karl!");
	return 0;
} 
posted @ 2020-02-20 11:08  ylxmf2005  阅读(8)  评论(0)    收藏  举报