题面

Description

ADN公司内部共 n个员工,员工之间可能曾经因为小事有了过节,总是闹矛盾。若员工u和员工 v有矛盾,用边(u, v)表示,共 m个矛盾。最近,ADN公司内部越来越不团结,Amber决定裁员。Amber想得到一个被裁人员的清单,使得被裁人员间的不团结率最高。不团结率定义为被裁人员间的矛盾总数与被裁人员数的比值(不团结率=被裁人员之间的矛盾总数/被裁人员数)。

在上图这个例子中1, 2, 4和5,4个人中都有5对矛盾,则不团结率为\(\frac 45\)。如果我们添加3到这个团队,则不团结率就下降到\(\frac 56\)。

Input

  输入文件的第一行包含两个整数n和m (1≤n≤100,0≤m≤1000),n表示公司的总人数(编号从1到n),m表示矛盾的对数。

  接下来m行,每行两个整数ai和bi(1≤ai,bi≤n,ai≠bi),描述一对矛盾,每对矛盾只会出现一次。

Output

  输出文件的第一行为一个整数k(1≤k≤n),表示最不团结的团队总人数。

Sample Input

sample input #1

5 6

1 5

5 4

4 2

2 5

1 2

3 1

sample input #2

4 0

Sample Output

sample output #1

4

sample output #2

1

Hint

Note, that in the last example any team has hardness factor of zero, and any non-empty list of people is a valid answer.

题目分析

最大密度子图模板题。

假设答案为\(k\) ,则要求解的问题是:

选出一个合适的点集 \(V\) 和边集 \(E\),令\((|E|−k∗|V|)\)取得最大值。

所谓“合适”是指满足如下限制:若选择某条边,则必选择其两端点。

建图:

以原图的边作为左侧顶点,权值为\(1\);

原图的点作为右侧顶点,权值为\(+k\)。

若原图中存在边 \((u,v)\),则新图中添加两条边 \(([uv]−>u),([uv]−>v)\),转换为最大权闭合子图

代码实现

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#define MAXN 0x7fffffff
#define eps 1e-9
typedef long long LL;
const int N=1105;
using namespace std;
inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}
int n,m,S,T,num;
struct node{int next,to,pair;double flow;}g[N<<3];
struct Edge{int x,y;}s[N];
int h[N],cnt;
void AddEdge(int x,int y,double z){
g[++cnt].to=y,g[cnt].next=h[x],h[x]=cnt,g[cnt].flow=z,g[cnt].pair=cnt+1;
g[++cnt].to=x,g[cnt].next=h[y],h[y]=cnt,g[cnt].flow=0,g[cnt].pair=cnt-1;
}
int GAP[N],dis[N];
void Init(){
static int q[N];
fill(dis,dis+num,0),fill(GAP,GAP+num,0);
int l=0,r=1;q[++l]=T,++GAP[dis[T]=1];
while(l<=r){
int x=q[l++];
for(int i=h[x];i;i=g[i].next){
int to=g[i].to;
if(!dis[to])++GAP[dis[to]=dis[x]+1],q[++r]=to;
}
}
}
double Dfs(int x,double Maxf){
if(x==T||!Maxf)return Maxf;
double ret=0;
for(int i=h[x];i;i=g[i].next){
int to=g[i].to;
if(g[i].flow&&dis[x]==dis[to]+1){
double dlt=Dfs(to,min(g[i].flow,Maxf-ret));
g[i].flow-=dlt;
g[g[i].pair].flow+=dlt;
ret+=dlt;
if(dis[S]==num+1||ret+eps>=Maxf)return ret;
}
}
if(!(--GAP[dis[x]]))dis[S]=num+1;
else GAP[++dis[x]]++;
return ret;
}
double SAP(){
Init();
double ans=Dfs(S,MAXN);
while(dis[S]<=num)ans+=Dfs(S,MAXN);
return ans;
}
bool Check(double mid){
fill(h,h+num,0),cnt=0;
for(int i=1;i<=m;i++)AddEdge(S,i,1),AddEdge(i,s[i].x+m,MAXN),AddEdge(i,s[i].y+m,MAXN);
for(int i=1;i<=n;i++)AddEdge(i+m,T,mid);
return m-SAP()>0;
}
int ans;bool vis[N];
void Find(int x){
ans+=(x>m&&x<=m+n);
vis[x]=1;
for(int i=h[x];i;i=g[i].next){
int to=g[i].to;
if(g[i].flow&&!vis[to])Find(to);
}
}
int main(){
n=Getint(),m=Getint(),S=0,T=n+m+1,num=T+1;
if(!m)cout<<1,exit(0);
for(int i=1;i<=m;i++)s[i].x=Getint(),s[i].y=Getint();
double l=0,r=m,Eps=1.0/n/n;
while(l+Eps<r){
double mid=(l+r)/2;
if(Check(mid))l=mid;
else r=mid;
}
Check(l),Find(S);
cout<<ans;
return 0;
}

【POJ3155】生活的艰辛Hard Life的更多相关文章

  1. 这些年正Android - 大学

     还记得,第一次看见小周是在大一的操场上. 她正向教学楼站着,一身白配粉的休闲上衣搭配湖蓝色的牛仔裤,穿着一双很平凡的凉鞋,手里拿着当年的Nokia 3110c,皙清的手指,素颜的站着不言不笑.现在回 ...

  2. python 爬取腾讯微博并生成词云

    本文以延参法师的腾讯微博为例进行爬取并分析 ,话不多说 直接附上源代码.其中有比较详细的注释. 需要用到的包有 BeautifulSoup WordCloud jieba # coding:utf-8 ...

  3. 2018(上)C高级第0次作业

    一:已关注邹欣老师的博客,以及一些任课老师的博客. 二:新学期新气象,走过基础C语言的学习,转眼间来到了C语言的高级学习... 1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题. (1)最理想的师 ...

  4. 记一次重大生产事故,在那 0.1s 我想辞职不干了!

    一.发生了什么? 1.那是一个阳光明媚的下午,老婆和她的闺蜜正在美丽的湖边公园闲逛(我是拎包拍照的). 2.突然接到甲方运营小妹的微信:有个顾客线上付款了,但是没有到账,后台卡在微信支付成功(正常状态 ...

  5. 【8.28校内测试】【区间DP】

    感受到了生活的艰辛QAQ...这才是真正的爆锤啊...(因为t1t3还没有理解所以只能贴t2叻QAQ 区间DP...爆哭把题理解错了,以为随着拿的东西越来越多,断点也会越来越多,出现可以选很多的情况Q ...

  6. HDU2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活[多重背包]

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  7. hdu 2191 多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

    http://acm.hdu.edu.cn/showproblem.php?pid=2191 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的 ...

  8. ACM生活总结

    两年ACM生活总结 转眼已经踏入ACM这条不归路已经两年了, 深深的感觉到ACM的不易 和 艰辛,但同时ACM给我所带来的快乐,让我认为值一切都是值得的. 我刚上大学那会,我们学校的ACM刚刚起步不到 ...

  9. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 分类: dp 2015-05-21 10:50 14人阅读 评论(0) 收藏

    Description 急!灾区的食物依然短缺! 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并 ...

随机推荐

  1. fragment中的onCreateView和onViewCreated的区别和

    (1)  onViewCreated在onCreateView执行完后立即执行. (2)  onCreateView返回的就是fragment要显示的view.

  2. nginx信号及平滑升级

    1.nginx信号 nginx进程处理命令: kill -signals PID PID即nginx进程ID signals的参数解释如下所示: TERM,INT快速关闭进程 QUIT优雅的关闭,如果 ...

  3. 【转载】网易极客战记官方攻略-地牢-严酷考验 B

    关卡连接:https://codecombat.163.com/play/level/the-gauntlet-b 免费试玩:https://codecombat.163.com/play 使用你的所 ...

  4. 封装加减乘除函数 解决JS 浮点数计算 Bug

    计算机内部的信息都是由二进制方式表示的,即0和1组成的各种编码,但由于某些浮点数没办法用二进制准确的表示出来,也就带来了一系列精度问题.当然这也不是JS独有的问题. 例如, 我们在用JS做浮点运算会遇 ...

  5. 项目实战 - 混合式App开发

    为何要使用混合式开发? 要说为什么使用Hybrid App [混合式开发],就要先了解什么是Native App[原生程序], Web App[网站程序]. Native App 是专门针对某一类移动 ...

  6. JavaIO流之字节流

    什么是字节? 所谓字节(Byte),是计算机数据存储的一种计量单位.一个二进制位称为比特(bit),8个比特组成一个字节,也就是说一个字节可以用于区分256个整数(0~255).由此我们可以知道,字节 ...

  7. Stream(Java 8)

    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (b ...

  8. SQL LIKE 运算符

    SQL LIKE 运算符 在WHERE子句中使用LIKE运算符来搜索列中的指定模式. SQL LIKE 操作符 LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. 有两个通配符与LIKE运 ...

  9. thinkphp 图形处理

    使用Think\Image类进行图像处理功能,支持Gd库和Imagick库,包括对GIf图像处理的支持. 实例化类库 $image = new \Think\Image(); 默认使用GD库进行图像操 ...

  10. Shiro学习(3)授权

    授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等).在授权中需了解的几个关键对象:主体(Subject).资源(Resource).权限(Permission).角 ...