【01分数规划】最大密度子图
2014-11-29 07:35
405 查看
http://www.cnblogs.com/gufeiyang/archive/2012/10/04/2711618.html
题意:给出一个无向图, 求这个无向图的最大密度子图。 就是选择一个子图,使边的数目比上点的数目最大,并且输出方案。
思路: 这道题真心不会。 可以确定的是一道01规划的问题。我们依旧是二分答案g。然后就是按照网上其他人的建图方案做的。
“采用0-1整数规划的思想来求最优解。使用二分查找的方法来求g(h), 初始left = 0, right = m。对于每一个g=(left+right)/2可以建立一个新图。在新图中源点与原图中每一个点连一条容量为m的边。原图中每一条边与汇点连一条容量为m+2*g-dv的边。dv为点v的度数。再将原图中的无向边拆成两条有向边,容量都设为1.然后对此图求最大流(maxflow)。最后将(n*m-maxflow)/2
与0比较大小,如果它大于0,则left=g,否则right = g。”
最后从s出发搜索(如果有流量往前搜),能搜到的标号在1到n之间的点就是选择的点的方案。
题意:给出一个无向图, 求这个无向图的最大密度子图。 就是选择一个子图,使边的数目比上点的数目最大,并且输出方案。
思路: 这道题真心不会。 可以确定的是一道01规划的问题。我们依旧是二分答案g。然后就是按照网上其他人的建图方案做的。
“采用0-1整数规划的思想来求最优解。使用二分查找的方法来求g(h), 初始left = 0, right = m。对于每一个g=(left+right)/2可以建立一个新图。在新图中源点与原图中每一个点连一条容量为m的边。原图中每一条边与汇点连一条容量为m+2*g-dv的边。dv为点v的度数。再将原图中的无向边拆成两条有向边,容量都设为1.然后对此图求最大流(maxflow)。最后将(n*m-maxflow)/2
与0比较大小,如果它大于0,则left=g,否则right = g。”
最后从s出发搜索(如果有流量往前搜),能搜到的标号在1到n之间的点就是选择的点的方案。
#include <cstdio> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <iostream> using namespace std; const int N = 201, M = 10100; const double INF = 10000000000; struct EDGE { int u, v, next; double cap; }edge[M]; int map[M][2], n, m, dis , cur , gap , pre ; int num, head , d , step, path , s, t; bool used ; void init() { memset(d, 0, sizeof(d)); for (int i=1; i<=m; i++) { scanf("%d%d", &map[i][0], &map[i][1]); d[map[i][0]]++; d[map[i][1]]++; } } void add(int u, int v, double w) { edge[num].u = u; edge[num].v = v; edge[num].cap = w; edge[num].next = head[u]; head[u] = num++; } double SAP(int s, int t) { memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); int i; for(int i = 1;i <= t;i++) cur[i] = head[i]; int top = s; gap[s] = t; double maxflow = 0,flow = INF; while(dis[s] < t) { for(i = head[top];i != -1;i = edge[i].next) { if(edge[i].cap > 0&& dis[top] == dis[edge[i].v] + 1) break; } if(i != -1) { cur[top] = i; int v = edge[i].v; if(edge[i].cap < flow) flow = edge[i].cap; top = v; pre[v] = i; if(top == t) { maxflow += flow; while(top != s) { edge[pre[top]].cap -= flow; edge[pre[top]^1].cap += flow; top = edge[pre[top]^1].v; } flow = INF; } } else { if(--gap[dis[top]] == 0) break; dis[top] = t; cur[top] = head[top]; for(int j = head[top];j != -1;j = edge[j].next) { if(edge[j].cap > 0&& dis[edge[j].v] + 1 < dis[top]) { dis[top] = dis[edge[j].v] + 1; cur[top] = j; } } gap[dis[top]]++; if(top != s) { top = edge[pre[top]^1].v; } } } return maxflow; } double makegraph(double g) { num = 0; memset(head, -1, sizeof(head)); for(int i=1; i<=n; i++) { add(s, i, m); add(i, s, 0); add(i, t, m+2*g-d[i]); add(t, i, 0); } for(int i=1; i<=m; i++) { add(map[i][0], map[i][1] , 1); add(map[i][1], map[i][0] , 0); add(map[i][1], map[i][0] , 1); add(map[i][0], map[i][1] , 0); } return n*m - SAP(s, t); } void dfs(int u) { used[u] = 1; if(u>=1 && u<=n) path[++step] = u; int v; for(int i=head[u]; i!=-1; i=edge[i].next) { v = edge[i].v; if(edge[i].cap >0 && !used[v]) dfs(v); } } void solve() { if(m == 0) { printf("1\n1\n"); return ; } double left=0, right=m, mid, esp = 1.0/n/n/2; double now; s = n+1; t = n+2; while(right-left > esp) { mid = (left+right)/2; now = makegraph(mid); if(now > 0) left = mid; else right = mid; } makegraph(left); memset(used, 0, sizeof(used)); step = 0; dfs(s); printf("%d\n", step); sort(path+1, path+step+1); for(int i=1; i<=step; i++) printf("%d\n", path[i]); } int main() { while(scanf("%d%d", &n, &m) != EOF) { init(); solve(); } return 0; }
相关文章推荐
- poj 3155 Hard Life(最大密度子图,01分数规划)
- poj 3155 Hard Life(01分数规划+最大流--最大密度子图)
- POJ-3155-Hard Life(最大密度子图)(01分数规划+最小割)
- bzoj 3232 01分数规划+最大权封闭子图判定
- poj3155 Hard Life 【最大密度图 01分数规划】
- poj 3155(Hard Life)分数规划/最大密度子图
- 最大密集子图(01分数规划+二分+最小割)POJ3155
- poj 3155 01规划->最大密度密度子图->最大流
- 最大密集子图(01分数规划+二分+最小割)POJ3155
- poj 3155 Hard Life 【最大密度子图】 【0-1分数规划 + 最小割】
- BZOJ 4501: 旅行 01分数规划 最大权闭合子图
- POJ 3621 Sightseeing Cows 最大密度环 01分数规划
- gift 分数规划的最大权闭合子图
- BZOJ 4819: [Sdoi2017]新生舞会 01分数规划 二分图最大权匹配(KM算法)/费用流
- poj3621 Sightseeing Cows 【最大比例环 01分数规划】
- [Sdoi2017]新生舞会 [01分数规划 二分图最大权匹配]
- 网络流(最大密集度子图,分数规划):UvaLive 3709 Hard Life
- POJ - 3111 K Best 平均值最大(01分数规划)
- zoj 2676 Network Wars(01分数规划+最大流)
- poj2976 Dropping tests 【01分数规划】