Bzoj1312 / POJ3155 Neerc2006 Hard Life
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 459 Solved: 114
Description
Input
Output
Sample Input
1 5
5 4
4 2
2 5
1 2
3 1
Sample Output
HINT
Source
图论 最大密度子图 01分数规划 网络流
将人抽象成点,关系抽象成边,则“带来麻烦的人的对数/总人数”就是一个子图中边数/点数,这玩意儿叫做图的密度。
原题POJ3155 要求输出密度最大时的任一方案
这里要求输出密度最大时最多能选出多少个人。
设密度r=边数/点数,显然是一个01分数规划问题。
解法1:
将每条边看做一个点,对于原图中的一条无向边<u,v>,从代表<u,v>的点向点u和点v各连一条边,容量为INF;
从S向<u,v>连边,容量为1
从u和v向T连边,容量为r
↑原问题转化成了最大权闭合子图问题。
解法2:
证明见胡伯涛《最小割模型在信息学竞赛中的应用》
U=m
从S向u连边,容量为U
从v向T连边,容量为U+2*r-deg[v]
对于边<u,v>从u向v连边,容量为1
若$(m*n-maxflow)/2>0$说明r可以扩大
这样就求出了最大的r
再用这个r建一遍图,跑最大流,在残量网络上DFS就可以找出所有可选的点。
就可以过POJ3155
把输出方案去掉就可以过Bzoj1312
但是博主傻傻不能理解为什么这样贪心一定能选出最多的人
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const double eps=1e-;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct EG{
int x,y;
}eg[mxn<<];
int deg[mxn];
//
struct edge{
int v,nxt;
double f;
}e[mxn<<];
int hd[mxn],mct=;
inline void add_edge(int u,int v,double f){
e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=f;hd[u]=mct;return;
}
void insert(int u,int v,double f){
add_edge(u,v,f); add_edge(v,u,);
return;
}
//
int n,m,S,T,U;
int d[mxn];
bool BFS(){
memset(d,,sizeof d);
queue<int>q;
d[S]=;
q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(!d[v] && e[i].f>){
d[v]=d[u]+;
q.push(v);
}
}
}
return d[T];
}
double DFS(int u,double lim){
if(u==T)return lim;
double f=,tmp;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(d[v]==d[u]+ && e[i].f>eps && (tmp=DFS(v,min(lim,e[i].f)))){
e[i].f-=tmp;
e[i^].f+=tmp;
lim-=tmp;
f+=tmp;
if(fabs(lim)<eps)return f;
}
}
d[u]=;
return f;
}
double Dinic(){
double res=;
while(BFS())res+=DFS(S,INF);
return res;
}
void Build(double r){
memset(hd,,sizeof hd);mct=;
S=;T=n+;int i;
for(i=;i<=n;i++){
insert(S,i,U);
insert(i,T,U+*r-deg[i]);
}
for(i=;i<=m;i++){
add_edge(eg[i].x,eg[i].y,);
add_edge(eg[i].y,eg[i].x,);
}
return;
}
bool use[mxn];int cnt=;
void DFS(int u){
use[u]=;++cnt;
for(int i=hd[u];i;i=e[i].nxt){
if(!use[e[i].v] && e[i].f>eps){DFS(e[i].v);}
}
return;
}
void solve(){
double l=,r=m; U=m;
double X=1.0/n/n;
while(r-l>X){
double mid=(l+r)/;
Build(mid);
// printf("mid:%.3f\n",mid);
if((m*n-Dinic())/>=eps){
l=mid;
}else r=mid;
}
Build(l);Dinic();
return;
}
void init(){
memset(hd,,sizeof hd);mct=;
memset(use,,sizeof use);cnt=;
return;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
if(!m){printf("1\n1\n");continue;}
init();
for(int i=;i<=m;i++){
eg[i].x=read();eg[i].y=read();
++deg[eg[i].x];
++deg[eg[i].y];
}
solve();
DFS(S);
printf("%d\n",cnt-);
for(int i=;i<=n;i++)if(use[i])printf("%d\n",i);
break;
}
return ;
}
Bzoj1312 / POJ3155 Neerc2006 Hard Life的更多相关文章
- POJ3155 Hard Life
Time Limit: 8000MS Memory Limit: 65536K Total Submissions: 8482 Accepted: 2461 Case Time Limit: ...
- bzoj2503&poj3387[NEERC2006]IdealFrame
其实只是把别人的题解强行扩写了 写这篇题解之前我不会的预备知识: 欧拉通路:从图中一个点出发不重复地遍历所有边的路径(可以停在另一个点) 欧拉回路:从图中一个点出发不重复地遍历所有边的回路(必须回到出 ...
- 最大密集子图(01分数规划+二分+最小割)POJ3155
题意:给出一副连通图,求出一个子图令g=sigma(E)/sigma(V); h[g]=sigma(E)-g*sigma(V):设G是最优值 则当h[g]>0:g<G h[g]<0, ...
- bzoj1312
忘写题解了,经典的最大密度子图 可以类似分数规划的做,二分密度,然后转化为最大权闭合子图做,判断是否大于0 注意方案的输出 const eps=1e-6; lim=1e-12; inf=; type ...
- POJ3155 Hard Life [最大密度子图]
题意:最大密度子图 #include<iostream> #include<cstdio> #include<cstring> #include<algo ...
- BZOJ.1312.[Neerc2006]Hard Life(分数规划 最大权闭合子图)
BZOJ 最大密度子图. 二分答案\(x\),转为求是否存在方案满足:\(边数-x*点数\geq 0\). 选一条边就必须选两个点,所以可以转成最大权闭合子图.边有\(1\)的正权,点有\(x\)的负 ...
- poj3155 最大密度子图
求最大密度子图 记得在最后一次寻找的时候记得将进入的边放大那么一点点,这样有利于当每条边都满流的情况下会选择点 #include <iostream> #include <algor ...
- 【POJ3155】生活的艰辛Hard Life
题面 Description ADN公司内部共 n个员工,员工之间可能曾经因为小事有了过节,总是闹矛盾.若员工u和员工 v有矛盾,用边(u, v)表示,共 m个矛盾.最近,ADN公司内部越来越不团结, ...
- poj分类 很好很有层次感。
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. ( ...
随机推荐
- Android开发随笔5
昨天: 对界面的进一步设计补充 可以在界面之间的跳转 研究了对图标等的操作 今天: 实现对库的相关操作 学习视视频内容‘ 复习java的一些知识.
- 项目选题报告(I konw)
一.团队成员及分工 团队名称:I know 团队成员: 陈家权:选题报告word撰写 赖晓连:ppt制作,原型设计 雷晶:ppt制作,原型设计 林巧娜:原型设计,博客随笔撰写 庄加鑫:选题报告word ...
- 代替iframe的方法
$('#framecont').html('').load("pageURL"); 使用jQuery.
- Windows SDK 非模态对话框的消息处理
在SDK中使用非模态对话框时的几个问题: 1.为什么要调用IsDialogMessage?? 2.非模态对话框与主窗口有什么区别? 3.如果不调用IsDialogMessage,消息能不能传递到对话框 ...
- .net Mvc4 View—布局页与分部页
▲ 一.Layout属性 1.1.@RenderPage():渲染制定的页面到占位符. 注意:@RenderPage()可以使用多次,这点与@RenderBody()不同 ...
- Python2中编码错误---éç»äººè¡¨ç®çé¿å ååè¶(æå格式转化为UTF-8
在python2的使用中,总会遇到各种各样的编码问题,这也是使用Python2最头疼的一件事情,幸好python3解决了编码的问题. 下面我在爬虫时遇到的类似éç»äººè¡¨ç®çé¿ ...
- jira & analytics
jira & analytics jira 代码有毒呀 http://jira.xgqfrms.xyz:8888/rest/analytics/1.0/publish/bulk { resou ...
- 移除 ios 上 input 的默认样式
input{ -webkit-appearance:none; }
- overflow:scroll 滚动条不显示
overflow:scroll 滚动条不显示 ::-webkit-scrollbar-thumb 可能因为 自定义的滚动条height比元素可展示内容大
- 【bzoj5107】[CodePlus2017]找爸爸 dp
题目描述 给出两个基因串,你需要在其中插入任意个空格,使得两个串长度相同.如果两个串的某同一位置都是字母则获得某给定收益,对于每个串的每个长度为k的连续空格段要付出a(k-1)+b的损失.求最大净收益 ...