习题7-4 切断圆环链(Cutting Chains, ACM/ICPC World Finals 2000, UVa818)

来源:互联网 发布:mac用什么炒股软件 编辑:程序博客网 时间:2024/04/30 07:07
思路:枚举所有的拆分方式,判断是否有某个点degree > 2 及是否有环,记录最小的cut_num。
1. 无向图的dfs判环,需要标记前驱节点。
2. 以vector存图时要注意输入重边的存在(坑啊,wa了两个点。。),小图可以用G[][]来存。
#include <iostream>#include <string>#include <vector>#include <stack>#include <queue>#include <deque>#include <set>#include <map>#include <algorithm>#include <sstream>#include <utility>#include <cstring>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define LL long long#define mod 1000000007#define INF 10000007#define eps 1e-5#define PI 3.1415926535898using namespace std;//-------------------------CHC------------------------------//const int maxn = 20;int n;vector<int> G[maxn];bool cut[maxn], vis[maxn];int component, cut_num;void calc_cut(int subset) {CLEAR(cut, 0);cut_num = 0;for (int i = 0; i < n; ++i) {if ((1 << i) & subset) cut[n - i] = true, ++cut_num;}}bool too_much() {for (int i = 1; i <= n; ++i) {if (cut[i]) continue;int deg = 0;for (int j = 0; j < G[i].size(); ++j)if (!cut[G[i][j]]) ++deg;if (deg > 2) return true;}return false;}bool dfs(int u, int f) {vis[u] = true;for (int i = 0; i < G[u].size(); ++i) {int v = G[u][i];if (!cut[v] && v != f) {if (vis[v]) return true;else if (dfs(v, u)) return false;}}return false;}bool have_circle() {CLEAR(vis, 0);component = 0;for (int i = 1; i <= n; ++i)if (!vis[i] && !cut[i]) {if (dfs(i, -1)) return true;component++;}return false;}int main() {int kase = 1;while (~scanf("%d", &n) && n) {for (int i = 0; i < maxn; ++i) G[i].clear();int u, v;while (scanf("%d%d", &u, &v)) {if (u == -1 || v == -1) break;G[u].push_back(v);G[v].push_back(u);}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());}int ans = n;for (int i = 0; i < (1 << n); ++i) {calc_cut(i);if (too_much() || have_circle()) continue;if(component <= cut_num + 1) ans = min(ans, cut_num);}printf("Set %d: Minimum links to open is %d\n", kase++, ans);}return 0;}

阅读全文
0 0
原创粉丝点击