点边都带权的最大密度子图,且会有必须选的点.

求\(\frac{\sum w_e}{k*(2n-k)}\)的最大值,其中k为子图点数

设$$h(g) = \sum w_e - g*(2nk-k^2)$$

假设最优解为\(g*\),则当\(g<g*\)时,\(h(g)>0\);\(g>g*时,h(g)<0\),以此判断条件二分搜索.

但是\((2nk-k^2)\)不能直接转化为点权,需要做点改变.

\[\sum w_e - g*2nk+g*k^2 = \sum w_e + \frac{k(k-1)}{2}*2g+kg-2kng
\]

\[= \sum (w_e + 2g) - (2ng-g)*k
\]

这个式子的意义等于对原图的每一条边都加上了边权2g,若原图两点间没有边,则新建一条权值为2g的边. 每个点的点权为\((2ng-g)\)

这样就转化成了点边均带权的最大密度子图模型.

还有一些必须要选的点.因为在最大权闭合子图的模型中,若源点S与点i之间的边不是割,则表示没有选择这个点.根据这个性质,我们在建图的时候对必须选的点,只从源点S向它建边,容量为正无穷,保证它不会成为割中的边.然后在总的流量中加上这个点的点权.

第二十组数据特别卡精度,但是eps设得过高会T.

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-7;
const int INF = 0x3f3f3f3f;
const int MAXN= 405;//点数的最大值
const int MAXM= 1e6 + 10;//边数的最大值
#define captype double
struct Edge{
int from,to,next;
captype cap;
}; struct SAP_MaxFlow{
Edge edges[MAXM];
int tot,head[MAXN];
int gap[MAXN];
int dis[MAXN];
int cur[MAXN];
int pre[MAXN]; void init(){
tot=0;
memset(head,-1,sizeof(head));
}
void AddEdge(int u,int v,captype c,captype rc=0){
edges[tot] = (Edge){u,v,head[u],c}; head[u]=tot++;
edges[tot] = (Edge){v,u,head[v],rc}; head[v]=tot++;
}
captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
pre[sNode] = -1;
gap[0]=n;
captype ans=0;
int u=sNode;
while(dis[sNode]<n){
if(u==eNode){
captype Min=INF ;
int inser;
for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to])
if(Min>edges[i].cap){
Min=edges[i].cap;
inser=i;
}
for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to]){
edges[i].cap-=Min;
edges[i^1].cap+=Min;
}
ans+=Min;
u=edges[inser^1].to;
continue;
}
bool flag = false;
int v;
for(int i=cur[u]; i!=-1; i=edges[i].next){
v=edges[i].to;
if(edges[i].cap>0 && dis[u]==dis[v]+1){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
int Mind= n;
for(int i=head[u]; i!=-1; i=edges[i].next)
if(edges[i].cap>0 && Mind>dis[edges[i].to]){
Mind=dis[edges[i].to];
cur[u]=i;
}
gap[dis[u]]--;
if(gap[dis[u]]==0) return ans;
dis[u]=Mind+1;
gap[dis[u]]++;
if(u!=sNode) u=edges[pre[u]^1].to; //退一条边
}
return ans;
}
}F; int N, M ;
double d[MAXN];
int tag[MAXN];
int G[405][405]; #define U (400 * 2100) bool check(double g)
{
int s = 0, t = N+1;
F.init();
double flow = 0;
for(int i=1;i<=N;++i){
d[i] = 0.0;
for(int j=1;j<=N;++j){
if(i==j) continue;
d[i] += 2*g + G[i][j];
F.AddEdge(i,j,G[i][j] + 2*g);
}
} for(int i=1;i<=N;++i){
if(tag[i]){
flow += U + 2*g*(2*N-1) - d[i];
F.AddEdge(s, i, INF);
}
else{
F.AddEdge(s,i,U);
F.AddEdge(i,t, U + 2 * g * (2*N - 1) - d[i]);
}
} double hg = (U*N - flow - F.maxFlow_sap(s,t,t+1)) * 0.5;
return hg > eps;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int u,v,w;
scanf("%d %d",&N, &M);
for(int i=1;i<=M;++i){
scanf("%d %d %d",&u, &v, &w);
G[u][v] = G[v][u] = w;
}
for(int i=1;i<=N;++i){
scanf("%d",&tag[i]);
}
double L = 0, R = 200, mid;
while(R - L >= eps){
mid = (L+R) * 0.5;
if(check(mid)) L = mid;
else R = mid;
}
printf("%.6f\n",(L+R)*0.5);
return 0;
}

2017 计蒜之道 初赛 第三场 D. 腾讯狼人杀 (点边都带权的最大密度子图)的更多相关文章

  1. 计蒜之道 初赛 第三场 题解 Manacher o(n)求最长公共回文串 线段树

    腾讯手机地图 腾讯手机地图的定位功能用到了用户手机的多种信号,这当中有的信号的作用范围近.有的信号作用的范围则远一些.有的信号相对于用户在不同的方位强度是不同的,有的则是在不论什么一个方向上信号强度都 ...

  2. 2017 计蒜之道 初赛 第五场 UCloud 的安全秘钥(中等)

    每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作.作为一家安全可信的云计算平台,秘钥的安全性至关重要.因此,UCloud 每年会对用户的秘钥进行安全性评估,具体的评估方 ...

  3. 2017 计蒜之道 初赛 第五场 D. UCloud 的安全秘钥(困难)

    小数据打表,大数据暴力. 导致超时的主要原因是$m$小的询问次数太多,可以把$m≤10$的答案直接暴力打表存起来,$m>10$的用$C$题的方法即可. #include <iostream ...

  4. 2017 计蒜之道 初赛 第五场 C. UCloud 的安全秘钥(中等)

    暴力. $O(m*n)$的算法可以通过此题,每次询问$O(m)$扫$S$数组,统计不同数字的个数,每次移动最多只会变化两个数字,如果不同数字个数为$0$,那么答案加$1$. #include < ...

  5. 2017 计蒜之道 初赛 第五场 B. UCloud 的安全秘钥(简单)

    暴力. 暴力枚举$S$串的每一个长度为$m$的子串,排序判断即可. #include <iostream> #include <cstdio> #include <cst ...

  6. 2017 计蒜之道 初赛 第五场 A. UCloud 机房的网络搭建

    贪心. 从大到小排序之后进行模拟,注意$n=1$和$n=0$的情况. #include <iostream> #include <cstdio> #include <cs ...

  7. 2017 计蒜之道 初赛 第一场 A、B题

    A题 阿里的新游戏 题目概述: 阿里九游开放平台近日上架了一款新的益智类游戏——成三棋.成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示: 成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋 ...

  8. 2017 计蒜之道 初赛 第一场 A 阿里的新游戏

    题链:https://nanti.jisuanke.com/t/15499 这题观察图纸可知成三线段上的相邻点之间的距离有1,2,3三种情况的,同时要成线段必然是同横坐标或者纵坐标,然后我们排除掉穿过 ...

  9. 2017 计蒜之道 初赛 第一场 B阿里天池的新任务(简单)

    题链:"https://nanti.jisuanke.com/t/15500" 本来希望通过找循环节然后套KMP来通过后面题的,可是只过了B题,可能循环节不一定是存在的. #inc ...

随机推荐

  1. ssm异步上传图片

    1.首先引入jersey   jar包 2.在配置文件中,配置允许上传图片 3.修改增加商品页面 <%@ page language="java" import=" ...

  2. 第十一篇:Linux中权限的再讨论( 下 )

    前言 上篇随笔讲述了Linux中权限的大致实现机制以及目录权限的相关规则.本文将讲解Linux中的三种特殊权限:SUID,SGID,Sticky权限. 看完这两篇文章,你一定会对Linux的权限有个更 ...

  3. 解决ScrollView滑动RecyclerView的卡顿

    我们不的不了解ViewConfiguration这个类,官方是这么解释的Contains methods to standard constants used in the UI for timeou ...

  4. IOS6.0调用通讯录和之前的差别

    6.通讯录列表获取差异 自iOS6.0后获取通讯录列表需要询问用户,经过用户同意后才可以获取通讯录用户列表.而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函 ...

  5. 通过pymysql程序debug学习数据库事务、隔离级别

    问题 今天在使用pymysql连数据库的时候,出现了一个bug,查询数据库某个数据,但是在我在数据库中执行sql语句改变数据后,pymsql的查询依然没有发生改变. 代码如下: # 5.6.10 co ...

  6. Elasticsearch 中文分词(elasticsearch-analysis-ik) 安装

    由于elasticsearch基于lucene,所以天然地就多了许多lucene上的中文分词的支持,比如 IK, Paoding, MMSEG4J等lucene中文分词原理上都能在elasticsea ...

  7. ipconfig /flushdns

    C:\Users\sas>ipconfig /flushdns Windows IP 配置 已成功刷新 DNS 解析缓存. C:\Users\sas>ipconfig --help 错误: ...

  8. jquery.dragsort.js 实现拖拽过程遇到的问题

    .在IE下第一次拖动的时候,被拖动的li元素会不显示,查了很多资料发现是因为在IE中定位出了问题,li标签还在,只是位置计算出错.解决的办法是在li的css样式中position设置为relative ...

  9. CentOS下调整home和根分区大小的方法

    解决外挂硬盘的问题. 目标:将VolGroup-lv_home缩小到20G,并将剩余的空间添加给VolGroup-lv_root 1.首先查看磁盘使用情况[root@jb51.net~]# df -h ...

  10. Robberies---hdu2955(概率dp,01背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 题目给了每个银行的钱和被抓的概率,由于要抢尽量多的钱,所以要保证尽量不被抓,而抢多个银行之后不被 ...