poj3155 Hard Life 【最大密度图 01分数规划】
来源:互联网 发布:淘宝介入后卖家的下场 编辑:程序博客网 时间:2024/05/23 12:51
链接:http://poj.org/problem?id=3155
题意:给你一个图,n个点,m条边,现在要你找到一个子图,求子图中的边数与点数的比值最大。
分析:《最小割模型在信息学竞赛中的应用》(胡伯涛著)中的论问题。
01分数规划套路。。:R=sigma(e)/sigma(v) 设 F(L)=sigma(e)-L*sigma(v),但是我们二分出L后并不知道取哪些边。但是我们知道取了(u,v)这条边,那么我们就一定要取u和v这两点,这就可以转换成求最大权闭合子图。我们可以将边和点看成同一种点,边连向u,v无穷大的边,s到边为1,u,v到t为L。F(L)=m-最小割。
代码:最好理解的建边,没优化的。。
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 2010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;const double eps=1e-5;struct edge { int v,next; double w;} e[Mm];int deep[Mn];int head[Mn];int cur[Mn];int N,tot;void addedge(int u,int v,double w) { e[tot].v=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++;}queue<int> q;bool bfs(int st,int en) { while(!q.empty()) q.pop(); CLR(deep,-1); q.push(st); deep[st]=0; while(!q.empty()) { int u=q.front(); q.pop(); if(u==en) return true; for(int i=head[u]; i!=-1; i=e[i].next) { int v=e[i].v; double w=e[i].w; if(w>0&&deep[v]==-1) { deep[v]=deep[u]+1; q.push(v); } } } return false;}double dfs(int u,double sum,int en) { if(u==en) return sum; double a=0,us=0; for(int &i=cur[u]; i!=-1; i=e[i].next) { if(deep[e[i].v]==deep[u]+1) { a=sum-us; a=dfs(e[i].v,min(a,e[i].w),en); e[i].w-=a; e[i^1].w+=a; if(e[i].w) cur[u]=i; us+=a; if(us==sum) return sum; } } if(!us) deep[u]=-1; return us;}double dinic(int st,int en) { double ans=0; while(bfs(st,en)) { CPY(cur,head); ans+=dfs(st,INF,en); } return ans;}int n,m;int u[Mn],v[Mn];void init() { tot=0; CLR(head,-1);}bool check(double x) { init(); int cnt=0; int s=0,t=n+m+1; for(int i=1;i<=m;i++) { cnt++; addedge(s,n+cnt,1); addedge(n+cnt,s,0); addedge(n+cnt,u[i],INF); addedge(u[i],n+cnt,0); addedge(n+cnt,v[i],INF); addedge(v[i],n+cnt,0); } for(int i=1;i<=n;i++) { addedge(i,t,x); addedge(t,i,0); } double ans=1.0*m-dinic(s,t); if(fabs(ans)>eps) return true; return false;}int vis[Mn];int num=0;void findv(int u) { vis[u]=1; if(u<=n&&u>=1) num++; for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(!vis[v]&&e[i].w>0) findv(v); }}int main() { scanf("%d%d",&n,&m); if(!m) { printf("1\n1\n"); return 0; } for(int i=1;i<=m;i++) { scanf("%d%d",&u[i],&v[i]); } double l=1.0/n,r=m; while(fabs(r-l)>eps) { double mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; } check(l); findv(0); printf("%d\n",num); for(int i=1;i<=n;i++){ if(vis[i]) printf("%d\n",i); } return 0;}
0 0
- poj3155 Hard Life 【最大密度图 01分数规划】
- [POJ3155]Hard Life(01分数规划)
- poj 3155(Hard Life)分数规划/最大密度子图
- poj3155 Hard Life 最小割 最大密度子图
- poj3155--Hard Life(最大密度子图)
- 【POJ3155】【网络流】【最大密度子图】Hard Life 题解
- poj 3155 Hard Life(01分数规划+最大流--最大密度子图)
- 【POJ3155】Hard Life 分数规划+最小割
- poj 3155 Hard Life(最大密度子图,01分数规划)
- POJ-3155-Hard Life(最大密度子图)(01分数规划+最小割)
- poj 3155 Hard Life 【最大密度子图】 【0-1分数规划 + 最小割】
- 【01分数规划】最大密度子图
- POJ3155-最大密度子图
- POJ3155【最大密度子图】
- poj3155 最大密度子图
- 最大密度子图poj3155
- 最大密集子图(01分数规划+二分+最小割)POJ3155
- POJ3155--Hard Life
- sqlite3_column
- JDBC查看数据表结构
- 实用工具:VS上python开发插件(python tools for visual studio)
- Java入门级知识小结
- HDU 5444-二叉树的遍历+建树
- poj3155 Hard Life 【最大密度图 01分数规划】
- ActiveMQ学习(四)企业级应用配置详解
- php生成随机验证码
- 使用Windows API进行GDI窗口绘图
- 【HDU】-5326-Work(反向拓扑)
- HDU-2120-Ice_cream's world I【并查集】
- 大数据Spark “蘑菇云”行动前传第13课Scala模式匹配实战和Spark源码鉴赏
- 排序
- 二叉搜索树的后序遍历序列