poj 3155 Hard Life(最大密度子图,01分数规划)
来源:互联网 发布:mac办公软件收费吗 编辑:程序博客网 时间:2024/06/06 05:21
http://poj.org/problem?id=3155
大致题意:给出一个无向图,求出它的一个最大密度子图,最大密度子图定义为子图的边数与顶点数的比值。
详见amber论文中关于最大密度子图
本题要注意的地方:
当m为0时也要输出内容。
二分的边界是 1/n/n(high - low >1/n/n) ,这在amber论文引理4.1中有讲解
因为h函数的特性,恒有h >=0,即h函数不是一个严格递减的函数,当减小到0时便不再减小。那么我们要取得的是第一个为0的,所以要二分下界,而不是直接取mid,因为没有意识到函数特性,WA了N次。
二分完毕后,并不能求出正确的low值,ms也是因为该函数的特性,我们还要再求一遍最大流。
根据残量网络求最大密度子图:从源点dfs,走残量网络中流量大于0的边并标记。
#include <stdio.h>#include <iostream>#include <algorithm>#include <set>#include <map>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#define LL long long#define _LL __int64#define eps 1e-8using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 110;const int maxm = 1010;struct node{int u,v;double w;int next,rev;}p[maxm],edge[maxm*6];int s,t,n,m,nn;int cnt,head[maxn];int d[maxn];int dist[maxn],vis[maxn];int ans;void init(){cnt = 0;memset(head,-1,sizeof(head));}void add(int u, int v, double w){edge[cnt] = (struct node){u,v,w,head[u],cnt+1};head[u] = cnt++;edge[cnt] = (struct node){v,u,0,head[v],cnt-1};head[v] = cnt++;}void build(double mid){init();for(int i = 1; i <= m; i++){add(p[i].u,p[i].v,1.0);add(p[i].v,p[i].u,1.0);}for(int i = 1; i <= nn; i++){add(s,i,m);add(i,t,m*1.0+2*mid-d[i]*1.0);}}bool bfs(){ queue <int> que; memset(dist, 0, sizeof(dist)); memset(vis, 0, sizeof(vis)); while(!que.empty()) que.pop(); vis[s] = 1; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(edge[i].w && !vis[v]) { que.push(v); vis[v] = 1; dist[v] = dist[u]+1; } } } if(dist[t] == 0)return false;return true;}double dfs(int u, double delta){ if(u == t) return delta; double ret = 0,tmp;for(int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].v;if(edge[i].w && dist[edge[i].v] == dist[u]+1 && (tmp = dfs(v,min(delta,edge[i].w)))){edge[i].w -= tmp;edge[edge[i].rev].w += tmp;return tmp;}}if(!ret) dist[u] = -1;return ret;}double Dinic(){ double ans = 0,res; while(bfs()) { while(res = dfs(s,INF))ans += res; } return ans;}void dfs_cut(int u){vis[u] = 1;if(u <= nn) ans++;for(int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].v;if(edge[i].w > 0 && !vis[v]){dfs_cut(v);}}}int main(){while(~scanf("%d %d",&n,&m)){if(m == 0){printf("1\n1\n");continue;}memset(d,0,sizeof(d));for(int i = 1; i <= m; i++){scanf("%d %d",&p[i].u,&p[i].v);d[p[i].u]++;d[p[i].v]++;}s = n+1;t = n+2;nn = n;n = t;double low,high,mid,h;low = 0.0;high = m;while(high - low > 1.0/nn/nn){mid = (high + low)/2;build(mid);h = (m*nn*1.0 - Dinic() )/2;if(h > eps)low = mid;else high = mid;}build(low);Dinic();ans = 0;memset(vis,0,sizeof(vis));dfs_cut(s);printf("%d\n",ans);for(int i = 1; i <= nn; i++){if(vis[i])printf("%d\n",i);}}return 0;}
0 0
- poj 3155(Hard Life)分数规划/最大密度子图
- poj 3155 Hard Life(01分数规划+最大流--最大密度子图)
- poj 3155 Hard Life(最大密度子图,01分数规划)
- POJ-3155-Hard Life(最大密度子图)(01分数规划+最小割)
- poj 3155 Hard Life 【最大密度子图】 【0-1分数规划 + 最小割】
- poj3155 Hard Life 【最大密度图 01分数规划】
- POJ 3155 Hard Life 最大密度子图
- POJ 3155 Hard Life 最大密度子图
- POJ 3155 Hard Life 最大密度子图
- 【POJ】3155 Hard Life 最大密度子图
- poj 3155 Hard Life(最大密度子图)
- POJ 3155 Hard Life(最大密度子图)
- poj 3155 Hard Life 最大密度子图
- POJ 3155 Hard Life 最大密度子图
- poj 3155 Hard Life (最大密度子图)
- poj 3155 Hard Life (最大密度子图)
- poj 3155 Hard Life 最大密度子图
- POJ 3155 Hard Life(最大密度子图)
- 数据结构与算法分析10(排序-插入、冒泡、希尔、堆、归并)
- Holding Bin-Laden Captive!
- 关于对话框OnPaint 不调用基类CDialog::OnPaint方法CPU消耗很大达到70%以上问题
- week14闲来无事
- iOS开发准备篇-(3)Safari常用快捷键
- poj 3155 Hard Life(最大密度子图,01分数规划)
- Linux学习之CentOS(七)--CentOS下j2ee环境搭建
- Scripts:查询使用临时表空间最多的10个SQL htemp10.sql
- 利用ASP.NET DataGrid显示主次关系的数据
- 带分数
- LeetCode: Sqrt(x) [069]
- Scripts:查询排序最多的10个SQL hsort10.sql
- 设计ASP.NET新闻管理系统
- 数据结构与算法分析11(排序-快速排序及相关分析、排序分析)