SRM733Hard

题意

\(n\) 个点竞赛图哈密尔顿回路。

\(1\ \leq\ n\ \leq\ 50\)

做法1

结论是 \(n\) 个点竞赛图有哈密尔顿回路当且仅当 \(SCC\) 个数是 \(1\)
考虑每次增加一个点 \(i\),维护每个 \(SCC\) 哈密尔顿回路。
\(lst\) 为当前图 \(SCC\) 缩点后的链上最后一个有向连 \(i\) 边的点的 \(SCC\)
\(fst\) 为当前图 \(SCC\) 缩点后的链上第一个有从 \(i\) 连边的点的 \(SCC\)
\(lst\ <\ fst\) 则暴力插入。
\(lst\ =\ fst\) 则更新 \(lst\)
\(lst\ >\ fst\) 则合并 \(fst\)\(lst\) 中所有 \(SCC\)
总复杂度 \(O(n^2)\)

代码

#include<bits/stdc++.h>

using namespace std;

class HamiltonianCircuits { 
	public: 
	vector <int> findCircuit(int n, int seed, int a, int b, int c, vector <int> d, vector <int> e) {
		vector<vector<int> > g(n, vector<int>(n, 0));
		int value = seed;
		for (int i = 0; i < n; ++i) {
			for (int j = i + 1; j < n; ++j) {
				if(value % 1000 <= 250) {
					g[i][j] = 1;
					g[j][i] = -1;
				}
				else {
					g[i][j] = -1;
					g[j][i] = 1;
				}
				value = ((long long) a * value + b) % c;
			}
		}
		for (int i = 0; i < d.size(); ++i) g[d[i]][e[i]] = 1, g[e[i]][d[i]] = -1;
		vector<vector<int> > ans; vector<int> bel(n);
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < ans.size(); ++j) for (int u: ans[j]) bel[u] = j;
			int fst = n, lst = -1;
			for (int j = 0; j < i; ++j) {
				if(g[i][j] > 0) fst = min(fst, bel[j]);
				if(g[i][j] < 0) lst = max(lst, bel[j]);
			}
			if(fst > lst) {
				auto t = ans; ans.clear();
				for (int j = 0; j <= lst; ++j) ans.push_back(t[j]);
				ans.push_back(vector<int>{i});
				for (int j = lst + 1; j < t.size(); ++j) ans.push_back(t[j]);
				continue;
			}
			if(fst == lst) {
				auto t = ans[fst];
				for (int j = 0; j < t.size(); ++j) {
					int u = t[j], v = t[(j + 1) % t.size()];
					if(g[u][i] > 0 && g[i][v] > 0) {
						ans[fst].clear();
						for (int k = 0; k <= j; ++k) ans[fst].push_back(t[k]);
						ans[fst].push_back(i);
						for (int k = j + 1; k < t.size(); ++k) ans[fst].push_back(t[k]);
						break;
					}
				}
				continue;
			}
			auto t = ans; ans.clear();
			for (int j = 0; j < fst; ++j) ans.push_back(t[j]);
			ans.push_back(vector<int>{i});
			for (int j = 0; j < t[fst].size(); ++j) if(g[i][t[fst][j]] > 0) {
				ans.back().insert(ans.back().end(), t[fst].begin() + j, t[fst].end());
				ans.back().insert(ans.back().end(), t[fst].begin(), t[fst].begin() + j);
				break;
			}
			for (int j = fst + 1; j < lst; ++j) ans.back().insert(ans.back().end(), t[j].begin(), t[j].end());
			for (int j = 0; j < t[lst].size(); ++j) if(g[i][t[lst][j]] < 0) {
				ans.back().insert(ans.back().end(), t[lst].begin() + j + 1, t[lst].end());
				ans.back().insert(ans.back().end(), t[lst].begin(), t[lst].begin() + j + 1);
				break;
			}
			for (int j = lst + 1; j < t.size(); ++j) ans.push_back(t[j]);
		}
		return ans.size() == 1 ? ans[0] : vector<int>{};
	}
}; 
posted @ 2018-10-12 21:34  King_George  阅读(168)  评论(0编辑  收藏  举报