题面

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. OC开发系列-内存管理

    概述 移动设备的内存极其有限,每个app所有占用的内存是有限的.当app所占用的内存比较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间. 任何集成了NSObject的对象都需要手动进行 ...

  2. 使用mybatis时,sql查出来的结果映射不进逆向工程生成的该模型

    为了逆向工程生成驼峰效果,我们会在两个单词中间加_,但是在mybatis中,写sql语句时,要加别名,使别名和你逆向工程生成的该数据模型里面的属性名一致,否则查出来的结果映射不进去.

  3. 关于STLINK

    关于STLINK 1.STLIN固件升级 1)打开ST-LINK Utility,选择ST-LINK->Firmware update 2)连接ST-LINK 3)可以看到STLINK当前的软件 ...

  4. 第1篇Kubernetes介绍

      一.Kubernetes 介绍:     kubernetes起源 Kubernetes (K8s) 是 Google 在 2014 年发布的一个开源项目. 据说 Google 的数据中心里运行着 ...

  5. VMware下Ubuntu全屏显示

      开始是这样的 完了之后应该是这样的 1.点开菜单栏的 虚拟机---------> 安装VMware Tools 安装完了之后桌面会出现一个这样的图标 双击这个DVD,进去之后左侧目录出现了 ...

  6. redis-config.properties属性资源文件

    redis.host=192.168.200.128redis.port=6379redis.pass=redis.database=0redis.maxIdle=300redis.maxWait=3 ...

  7. 栈+括号序列+暴力枚举——cf1248D1

    这个复杂度首先就想到是n3的复杂度,n2枚举换的位置,求值在花费n复杂度 判断一个序列有多少独立的括号子串时用栈处理一下即可 /* 枚举交换两个括号的位置,然后再对新的序列判一次即可 */ #incl ...

  8. 合并vector里的内容,输出一个string

    string merge_vector(vector<string> dp_scpe_all) { //合并vector里的内容 string new_dp_scpe; ; m < ...

  9. java求两个数中的大数

    java求两个数中的大数 java中的max函数在Math中 应用如下: int a=34: int b=45: int ans=Math.max(34,45); 那么ans的值就是45.

  10. ElasticSearch Roaring bitmap 和跳表联合查询

    ElasticSearch Roaring map 先把所有数按65535划分, 划分方法就是求商和余数,商代表数字最终在哪一块,余数代表最终在块内的数字 比如 1, 65536, 65537, 13 ...