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)递归和分治法. ( ...
随机推荐
- pthon_flask小汇总
一.Jinja2中的关键字 1.include关键字 用include可以导入另外一个模板到当前模板中 <pre> {% include 'header.html' %} Body {% ...
- android平台蓝牙编程(转)
http://blog.csdn.net/pwei007/article/details/6015907 Android平台支持蓝牙网络协议栈,实现蓝牙设备之间数据的无线传输. 本文档描述了怎样利用a ...
- 3dContactPointAnnotationTool开发日志(十六)
调了一上午才发现是把下面这个函数: private float DivideTriangle(int []triangle,out int []outTriangle,List<Vector ...
- [剑指Offer] 48.不用加减乘除做加法
题目描述 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. [思路] 首先看十进制是如何做的: 5+7=12,三步走第一步:相加各位的值,不算进位,得到2.第二步:计算进 ...
- iOS-系统 图片、视频 管理控制器UIImagePickerController
UIImagePickerController 是一个管理系统多媒体文件库(相册)中的图片.视频文件的视图控制器,诞生于iOS4之前,虽然功能不是很完善,我们仍可以用这个视图控制器做一些有创造 ...
- CSS3 过渡效果触发时机的问题
像360deg过渡效果,做专题的同学应该是经常做的. <!DOCTYPE html> <html lang="en"> <head> <m ...
- Luogu1155 NOIP2008双栈排序(并查集)
两个位置i和j上的元素不能被放进同一个栈的充要条件显然是存在k使i<j<k且ak<ai<aj.由此在保证合法的情况下贪心地放就是正确的了. 至于如何判断,可以记一下后缀最小值, ...
- Flask的第一个应用
Flask 是一个 Python 实现的 Web 开发微框架,微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展. 与Django功能上比较: Django:中间件,路由系统,视图(CBV ...
- Django错误 OperationalError: no such column: xxx
模型前后操作如下: 第一次迁移: class Snippet(models.Model): created = models.DateTimeField(auto_now_add=True) titl ...
- 2017中国大学生程序设计竞赛-哈尔滨站 H - A Simple Stone Game
A Simple Stone Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Ot ...