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)递归和分治法. ( ...
随机推荐
- DAY3敏捷冲刺
站立式会议 工作安排 (1)服务器配置 (2)数据库配置 燃尽图 燃尽图有误,已重新修改,先贴卡片的界面,后面补修改后燃尽图 代码提交记录
- Xcode常见警告和错误
Xcode 升级后,常常遇到的遇到的警告.错误,解决方法 从sdk3.2.5升级到sdk 7.1中间废弃了很多的方法,还有一些逻辑关系更加严谨了.1,警告:“xoxoxoxo” is depreca ...
- TCP系列27—窗口管理&流控—1、概述
在前面的内容中我们依次介绍了TCP的连接建立和终止过程和TCP的各种重传方式.接着我们在这部分首先关注交互式应用TCP连接相关内容如延迟ACK.Nagle算法.Cork算法等,接着我们引入流控机制(f ...
- Qt单元测试(QTestLib)
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt单元测试(QTestLib) 本文地址:http://techieliang.co ...
- HDU 2133 What day is it
http://acm.hdu.edu.cn/showproblem.php?pid=2133 Problem Description Today is Saturday, 17th Nov,2007. ...
- dev_queue_xmit 发生了什么?skb还会在哪里缓存
见 codebox/net/qdisk/xmit.log中保存了一份记录 调用关系 sch_direct_xmit --> dev_hard_start_xmit --> xmit_one ...
- bzoj4502 串
题意:给你n(n<=10000)个字符串,每个字符串的长度不超过30,可以选择两个非空前缀把它们拼起来得到一个字符串(这两个前缀可以来自同一个字符串,也可以是同一个字符串的同一个非空前缀),问得 ...
- Openstack keystone组件详解
OpenStack Keystone Keystone(OpenStack Identity Service)是 OpenStack 框架中负责管理身份验证.服务规则和服务令牌功能的模块.用户访问资源 ...
- [洛谷P3979]遥远的国度
题目大意:有一棵$n$个点的树,每个点有一个点权,有三种操作: $1\;x:$把根变成$x$ $2\;u\;v\;x:$把路径$u->v$上的点权改为$x$ $3\;x:$询问以$x$为根的子树 ...
- Spring3 MVC 深入核心研究
[转载自 http://elf8848.iteye.com/blog/875830] 目录: 一.前言 二.核心类与接口 三.核心流程图 四.DispatcherServlet说明 五.双亲上下文的说 ...