2017 计蒜之道 初赛 第三场 D. 腾讯狼人杀 (点边都带权的最大密度子图)
点边都带权的最大密度子图,且会有必须选的点.
求\(\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)\)不能直接转化为点权,需要做点改变.
\]
\]
这个式子的意义等于对原图的每一条边都加上了边权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. 腾讯狼人杀 (点边都带权的最大密度子图)的更多相关文章
- 计蒜之道 初赛 第三场 题解 Manacher o(n)求最长公共回文串 线段树
腾讯手机地图 腾讯手机地图的定位功能用到了用户手机的多种信号,这当中有的信号的作用范围近.有的信号作用的范围则远一些.有的信号相对于用户在不同的方位强度是不同的,有的则是在不论什么一个方向上信号强度都 ...
- 2017 计蒜之道 初赛 第五场 UCloud 的安全秘钥(中等)
每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作.作为一家安全可信的云计算平台,秘钥的安全性至关重要.因此,UCloud 每年会对用户的秘钥进行安全性评估,具体的评估方 ...
- 2017 计蒜之道 初赛 第五场 D. UCloud 的安全秘钥(困难)
小数据打表,大数据暴力. 导致超时的主要原因是$m$小的询问次数太多,可以把$m≤10$的答案直接暴力打表存起来,$m>10$的用$C$题的方法即可. #include <iostream ...
- 2017 计蒜之道 初赛 第五场 C. UCloud 的安全秘钥(中等)
暴力. $O(m*n)$的算法可以通过此题,每次询问$O(m)$扫$S$数组,统计不同数字的个数,每次移动最多只会变化两个数字,如果不同数字个数为$0$,那么答案加$1$. #include < ...
- 2017 计蒜之道 初赛 第五场 B. UCloud 的安全秘钥(简单)
暴力. 暴力枚举$S$串的每一个长度为$m$的子串,排序判断即可. #include <iostream> #include <cstdio> #include <cst ...
- 2017 计蒜之道 初赛 第五场 A. UCloud 机房的网络搭建
贪心. 从大到小排序之后进行模拟,注意$n=1$和$n=0$的情况. #include <iostream> #include <cstdio> #include <cs ...
- 2017 计蒜之道 初赛 第一场 A、B题
A题 阿里的新游戏 题目概述: 阿里九游开放平台近日上架了一款新的益智类游戏——成三棋.成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示: 成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋 ...
- 2017 计蒜之道 初赛 第一场 A 阿里的新游戏
题链:https://nanti.jisuanke.com/t/15499 这题观察图纸可知成三线段上的相邻点之间的距离有1,2,3三种情况的,同时要成线段必然是同横坐标或者纵坐标,然后我们排除掉穿过 ...
- 2017 计蒜之道 初赛 第一场 B阿里天池的新任务(简单)
题链:"https://nanti.jisuanke.com/t/15500" 本来希望通过找循环节然后套KMP来通过后面题的,可是只过了B题,可能循环节不一定是存在的. #inc ...
随机推荐
- asp.net后台cs中的JSON格式变量在前台Js中调用方法(前后台示例代码)
//后台cs代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using ...
- 《Programming with Objective-C》第七章 Values and Collections
1.平台相关的数据类型 These types, like NSInteger and NSUInteger, are defined differently depending on the tar ...
- [转]这五种方法前四种方法只支持IE浏览器,最后一个方法支持当前主流的浏览器(火狐,IE,Chrome,Opera,Safari)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- JZOJ.5327【NOIP2017模拟8.21】四驱兄弟
Description
- ios 对日期的处理(包括计算昨天时间、明天时间)
NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间 Dates NSDate类提供了创建date,比较date以及计算两个date之间间隔的功能.Date对象是不可改变的. 如 ...
- 解决多指操作放大缩小 指针错误 java.lang.IllegalArgumentException: pointerIndex out of range
/** Custom your own ViewPager to extends support ViewPager. java source: */ /** Created by azi on 20 ...
- [LintCode] 寻找缺失的数
class Solution { public: /** * @param nums: a vector of integers * @return: an integer */ int findMi ...
- Python--paramiko库:连接远程服务器操作文件
import paramikofrom loggingutils.mylogger import logger as log class SSHConnection(object): def __in ...
- 使用response来控制浏览器的缓存
缓存这个技术在我们实际的开发中是非常常用的,也是非常重要的一项技术.主要用于客户端(浏览器)向服务器端请求的是一些比较大的数据,并且这个数据在短时间内不会经常发生变化的情况,比如一些网站的logo图片 ...
- python中的itertools
在量化数据处理中,经常使用itertools来完成数据的各种排列组合以寻找最优参数 import itertools #1. permutations: 考虑顺序组合元素 items = [1, 2, ...