UvaLive 3709 Hard Life(最大密度子图)
来源:互联网 发布:sqlmap mssql注入步骤 编辑:程序博客网 时间:2024/05/03 22:09
题目大意:求出最大的密度子图
解题思路:详见胡伯涛:算法合集之《最小割模型在信息学竞赛中的应用》
第一种解法,最大权闭合的解法
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define N 1110const double INF = 0x3fffffff;const int D_INF = 0x3f3f3f3f;const double esp = 1e-8;struct Edge { int from, to; double cap, flow; Edge() {} Edge(int from, int to, double cap, double flow): from(from), to(to), cap(cap), flow(flow) {}};struct ISAP { int p[N], num[N], cur[N], d[N]; int t, s, n, m; bool vis[N]; vector<int> G[N]; vector<Edge> edges; void init(int n) { this->n = n; for (int i = 0; i <= n; i++) { G[i].clear(); d[i] = D_INF; } edges.clear(); } void AddEdge(int from, int to, double cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; d[t] = 0; vis[t] = 1; Q.push(t); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i] ^ 1]; if (!vis[e.from] && e.cap - e.flow > esp) { vis[e.from] = true; d[e.from] = d[u] + 1; Q.push(e.from); } } } return vis[s]; } double Augment() { int u = t; double flow = INF; while (u != s) { Edge &e = edges[p[u]]; flow = min(flow, e.cap - e.flow); u = edges[p[u]].from; } u = t; while (u != s) { edges[p[u]].flow += flow; edges[p[u] ^ 1].flow -= flow; u = edges[p[u]].from; } return flow; } double Maxflow(int s, int t) { this->s = s; this->t = t; double flow = 0; BFS(); if (d[s] > n) return 0; memset(num, 0, sizeof(num)); memset(cur, 0, sizeof(cur)); for (int i = 0; i < n; i++) if (d[i] < D_INF) num[d[i]]++; int u = s; while (d[s] <= n) { if (u == t) { flow += Augment(); u = s; } bool ok = false; for (int i = cur[u]; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap - e.flow > esp && d[u] == d[e.to] + 1) { ok = true; p[e.to] = G[u][i]; cur[u] = i; u = e.to; break; } } if (!ok) { int Min = n; for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap - e.flow > esp) Min = min(Min, d[e.to]); } if (--num[d[u]] == 0) break; num[d[u] = Min + 1]++; cur[u] = 0; if (u != s) u = edges[p[u]].from; } } return flow; }};ISAP isap;#define maxn 1010int n, m, source, sink, Sum;int x[maxn], y[maxn];bool vis[maxn];void init() { for (int i = 1; i <= m; i++) scanf("%d%d", &x[i], &y[i]);}void build(double mid) { isap.init(sink); for (int i = 1; i <= m; i++) { isap.AddEdge(source, n + i, 1.0); isap.AddEdge(n + i, x[i], INF); isap.AddEdge(n + i, y[i], INF); } for (int i = 1; i <= n; i++) isap.AddEdge(i, sink, mid);}void dfs(int u) { vis[u] = true; if (u >= 1 && u <= n) Sum++; for (int i = 0; i < isap.G[u].size(); i++) { Edge &e = isap.edges[isap.G[u][i]]; if (!vis[e.to] && e.cap - e.flow > esp) dfs(e.to); }}void solve() { double l = 0, r = m, mid, ans; source = 0, sink = n + m + 1; while (r - l >= 1.0 / n / n) { mid = (l + r) / 2; build(mid); ans = isap.Maxflow(source, sink); if (1.0 * m - ans < esp) r = mid; else l = mid; } build(l); isap.Maxflow(source, sink); memset(vis, 0, sizeof(vis)); Sum = 0; dfs(source); printf("%d\n", Sum); for (int i = 1; i <= n; i++) if (vis[i]) printf("%d\n", i);}int main() { while (scanf("%d%d", &n, &m) != EOF) { if (!m) { printf("1\n1\n"); continue; } init(); solve(); } return 0;}
第二种解法:
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define N 1110#define INF 0x3f3f3f3fconst double Max = 0x3fffffff;const double esp = 1e-8;struct Edge { int from, to; double cap, flow; Edge() {} Edge(int from, int to, double cap, double flow): from(from), to(to), cap(cap), flow(flow) {}};struct ISAP { int p[N], num[N], cur[N], d[N]; int t, s, n, m; bool vis[N]; vector<int> G[N]; vector<Edge> edges; void init(int n) { this->n = n; for (int i = 0; i <= n; i++) { G[i].clear(); d[i] = INF; } edges.clear(); } void AddEdge(int from, int to, double cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; d[t] = 0; vis[t] = 1; Q.push(t); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i] ^ 1]; if (!vis[e.from] && e.cap - e.flow > esp) { vis[e.from] = true; d[e.from] = d[u] + 1; Q.push(e.from); } } } return vis[s]; } double Augment() { int u = t; double flow = Max; while (u != s) { Edge &e = edges[p[u]]; flow = min(flow, e.cap - e.flow); u = edges[p[u]].from; } u = t; while (u != s) { edges[p[u]].flow += flow; edges[p[u] ^ 1].flow -= flow; u = edges[p[u]].from; } return flow; } double Maxflow(int s, int t) { this->s = s; this->t = t; double flow = 0; BFS(); if (d[s] > n) return 0; memset(num, 0, sizeof(num)); memset(cur, 0, sizeof(cur)); for (int i = 0; i < n; i++) if (d[i] < INF) num[d[i]]++; int u = s; while (d[s] <= n) { if (u == t) { flow += Augment(); u = s; } bool ok = false; for (int i = cur[u]; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap - e.flow > esp && d[u] == d[e.to] + 1) { ok = true; p[e.to] = G[u][i]; cur[u] = i; u = e.to; break; } } if (!ok) { int Min = n; for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap - e.flow > esp) Min = min(Min, d[e.to]); } if (--num[d[u]] == 0) break; num[d[u] = Min + 1]++; cur[u] = 0; if (u != s) u = edges[p[u]].from; } } return flow; }};ISAP isap;#define maxn 1010#define maxm 110int n, m, source, sink, Sum;int x[maxn], y[maxn], in[maxm];bool vis[maxm];void init() { memset(in, 0, sizeof(in)); for (int i = 1; i <= m; i++) { scanf("%d%d", &x[i], &y[i]); in[x[i]]++; in[y[i]]++; }}void build(double mid) { isap.init(sink); for (int i = 1; i <= n; i++) { isap.AddEdge(source, i, m * 1.0); isap.AddEdge(i, sink, m + 2 * mid - in[i]); } for (int i = 1; i <= m; i++) { isap.AddEdge(x[i], y[i], 1.0); isap.AddEdge(y[i], x[i], 1.0); }}void dfs(int u) { vis[u] = true; if (u != source || u != sink) Sum++; for (int i = 0; i < isap.G[u].size(); i++) { Edge &e = isap.edges[isap.G[u][i]]; if (!vis[e.to] && e.cap - e.flow > esp) dfs(e.to); }}void solve() { source = 0, sink = n + 1; double l = 0, r = m, mid, ans; while (r - l >= 1.0/n/n) { mid = (r + l) / 2; build(mid); ans = isap.Maxflow(source, sink); if ((1.0 * n * m - ans) / 2 > esp) l = mid; else r = mid; } build(l); isap.Maxflow(source, sink); memset(vis, 0, sizeof(vis)); Sum = 0; dfs(source); printf("%d\n", Sum - 1); for (int i = 1; i <= n; i++) if (vis[i]) printf("%d\n", i);}int main() { while (scanf("%d%d", &n, &m) != EOF) { if (!m) { printf("1\n1\n"); continue; } init(); solve(); } return 0;}
0 0
- UvaLive 3709 Hard Life(最大密度子图)
- [PKU 3155]Hard Life(最大密度子图)
- poj 3155(Hard Life)分数规划/最大密度子图
- POJ 3155 Hard Life 最大密度子图
- poj3155 Hard Life 最小割 最大密度子图
- POJ 3155 Hard Life 最大密度子图
- POJ 3155 Hard Life 最大密度子图
- 【POJ】3155 Hard Life 最大密度子图
- POJ Hard Life (最大密度子图)
- poj 3155 Hard Life(最大密度子图)
- POJ 3155 Hard Life(最大密度子图)
- poj 3155 Hard Life 最大密度子图
- POJ 3155 Hard Life 最大密度子图
- poj3155--Hard Life(最大密度子图)
- poj 3155 Hard Life (最大密度子图)
- poj 3155 Hard Life (最大密度子图)
- 【POJ3155】【网络流】【最大密度子图】Hard Life 题解
- poj 3155 Hard Life 最大密度子图
- Android笔记:如何写出一个侧滑菜单
- 单元测试
- Mac上搭建本地svn服务器并使用cornerstone连接本地svn服务
- bzoj2594
- hdoj 3917 Road constructions 【最小割 之 最大权闭合图】
- UvaLive 3709 Hard Life(最大密度子图)
- Schema约束
- Hybrid App
- ESB-Mule-demo-实例
- 条款03 use const whenever possible
- 九度OJ 题目1147:Jugs
- hdu 3397(区间合并)
- UITextFiledView页面之间的相互传值
- #牛客#代码实现:字符串的匹配、字符串的交错组成、纸牌博弈、表达式组合