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

求\(\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. WPF 隧道路由事件

    阅读本文前,请先了解 冒泡路由事件:http://www.cnblogs.com/andrew-blog/p/WPF_BubbledEvent.html 隧道路由事件的工作方式和冒泡路由事件相同,但方 ...

  2. skeleton

    响应式模版 伯乐在线:http://hao.jobbole.com/skeleton/ cdn  : https://cdn.bootcss.com/skeleton/2.0.4/skeleton.c ...

  3. 一个网络设备的常见功能--连通性检查SSRF漏洞--被黑客利用当做扫描器

    一.我们先来看一下很多网络设备都有的一个常见功能--连通性测试: 很多网络设备都具备与其他设备通信,联动的功能,例如网络设备联动安全设备,网络设备联动认证设备等等.此时都需要一个对端IP和对端端口号作 ...

  4. ORA-01102的解决办法

    启动数据库时报错了! SQL> startup mount ORACLE instance started. Total System Global Area  608174080 bytes ...

  5. JPA criteria 查询:类型安全与面向对象

    参考:https://my.oschina.net/zhaoqian/blog/133500 一.JPA元模型概念,及使用 在JPA中,标准查询是以元模型的概念为基础的.元模型是为具体持久化单元的受管 ...

  6. MyBatis笔记——EhCache二级缓存

    介绍 ehcache是一个分布式缓存框架. 我们系统为了提高系统并发,性能.一般对系统进行分布式部署(集群部署方式)  不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发.所以要使用分布式缓 ...

  7. 160617、使用espeak将文字转语音(TTS)

    http://www.eguidedog.net/cn/WebSpeech_cn.php 简单使用例子: <html> <head> <meta http-equiv=& ...

  8. 进击的RecyclerView入门二(来点小装饰?)

    接着上一讲,我们看到我们的Demo可以正常的运行,并且能自动加载网络图片,那么为了后面观察的方便,我们取消这种自动加载的功能,使用两个按钮来代替,分别用来增加一个数据和减少一个数据.截图如下: 正在我 ...

  9. 自动生成项目的Makefile文件

    自动生成项目的Makefile文件 理论基础 跟我一起写 Makefile:   http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4 ...

  10. ArcGIS Server管理工具之批量发布动态地图服务工具.md

    友好阅读链接:(http://swj.me/2015/08/26/batchPublishtools/) update0918: 修复了创建链接文件时而出错的bug 修复了在24011的警告已处理的情 ...