bzoj 2285 [Sdoi2011]保密(二分,spfa + 最大流)
Description
现在,保密成为一个很重要也很困难的问题。如果没有做好,后果是严重的。比如,有个人没有自己去修电脑,又没有拆硬盘,后来的事大家都知道了。
当然,对保密最需求的当然是军方,其次才是像那个人。为了应付现在天上飞来飞去的卫星,军事基地一般都会建造在地下。
某K国的军事基地是这样子的:地面上两排大天井共n1个作为出入口,内部是许多除可以共享出入口外互不连通的空腔,每个空腔有且只有两个出入口,并且这两个出入口不会在同一排。为了方便起见,两排出入口分别编号为1,3,5…和2,4,6…并且最大的编号为n1。
虽然上面扯了那么多关于保密的东西,但是其实解密也是一件很纠结的事情。但其实最简单直接暴力无脑的解密方法就是找个人去看看。。。
我们有很牛X的特种部队,只需要派出一支特种部队到K国基地的某个出入口,那么和这个出入口直接相连的所有空腔都可以被探索,但也只有这些空腔可以被这支部队探索。现在有足够多的特种部队可以供你调遣,你必须使用他们调查完所有的K国基地内的空腔。
当然,你的基地离K国基地不会太近,周边的地图将会给你,表示为n个检查点和m条连接这些点的道路,其中点1到点n1就是K国基地的出入口,点n是你的部队的出发点。对每条道路,有不同的通行时间t和安全系数s。因为情报部门只对单向的道路安全系数进行了评估,所以这些道路只允许单向通行,并且不会存在环。
一支特种部队从你的基地出发,通过某条路径,到达某个K国基地出入口,此时这支部队的危险性表示为总时间和这条路径经过的所有道路的安全系数和的比值。整个行动的危险性表示为你派出的所有部队的危险性之和。你需要使这个值最小的情况下探索整个K国基地。
快点完成这个任务,在K国的叫兽宣布你是K国人之前。
Input
第一行2个正整数n,m (4 <= n <= 700, m <= 100000) 表示整个地区地图上的检查点和道路数。
下面m行,每行4个正整数a, b, t, s(a, b <=n, 1 <= t, s <= 10)表示一条从a到b的道路需时为t,安全系数为s。
接下来1行2个正整数m1和n1(m1 <= 40000, n1 < min{n, 161}), m1表示K国基地空腔的个数,n1表示K国基地出入口的个数。
再接下来m1行,每行2个正整数u, v (u, v<=n1, u是奇数,v是偶数),表示每个空腔的2个出入口。
Output
一行,最小的危险性,保留一位小数。或者输出”-1”(无引号)表示此任务不可能完成。
Sample Input
5 1 10 1
5 1 10 1
5 2 9 1
5 3 7 1
5 4 8 1
4 4
1 2
1 4
3 2
3 4
Sample Output
【思路】
二分,spfa + 最大流
首先求出从起点到所有出入口的危险性val,题目就是一个最小覆盖的问题,按照奇偶性将节点分作两组,奇数点由S向之连边val,偶数点向T连边val,跑个最大流就好了。
问题是怎么求出危险性。假设答案是ans,如果存在
(t1+t2+…tn)/(s1+s2+…sn)<=ans
即
t1-ans*s1+t2-ans*s2+…tn-ans*sn<=0
则说明存在更小ans。二分ans,每次跑一遍spfa求出最短路即可。
【代码】
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int N = ;
const double INF = 1e12;
const double eps = 1e-;
struct Edge{
int v; double t,s;
Edge(int v,double t,double s) :v(v),t(t),s(s) {}
};
struct Dedge {
int u,v; double cap,flow;
Dedge(int u,int v,double cap,double flow) :u(u),v(v),cap(cap),flow(flow) {}
}; void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)) {if(c=='-')f=-; c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
} struct Dinic {
vector<int> G[N];
vector<Dedge> es;
int n,m,s,t,d[N],cur[N],vis[N];
void init(int n) {
this->n=n;
es.clear();
for(int i=;i<n;i++) G[i].clear();
}
void AddEdge(int u,int v,double w) {
es.push_back(Dedge(u,v,w,));
es.push_back(Dedge(v,u,,));
m=es.size();
G[u].push_back(m-),G[v].push_back(m-);
}
bool bfs() {
int q[N],head=,tail=;
memset(vis,,sizeof(vis));
q[tail++]=s; vis[s]=; d[s]=;
while(head!=tail) {
int u=q[head++];
for(int i=;i<G[u].size();i++) {
Dedge& e=es[G[u][i]];
int v=e.v;
if(!vis[v]&&e.cap>e.flow) {
vis[v]=; d[v]=d[u]+;
q[tail++]=v;
}
}
}
return vis[t];
}
double dfs(int u,double a) {
if(u==t||fabs(a)<eps) return a;
double flow=,f;
for(int& i=cur[u];i<G[u].size();i++) {
Dedge& e=es[G[u][i]];
int v=e.v;
if(d[v]==d[u]+ && (f=dfs(v,min(a,e.cap-e.flow)))>eps) {
e.flow+=f;
es[G[u][i]^].flow-=f;
flow+=f; a-=f;
if(fabs(a)<eps) break;
}
}
return flow;
}
double Maxflow(int s,int t) {
this->s=s,this->t=t;
double flow=;
while(bfs()) {
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
} dc; vector<Edge> g[N];
int n,m,m1,n1; double val[N];
int head,tail,q[],vis[N]; double dis[N]; //spfa µÄ que bool spfa(int s,int t,double p) {
FOR(i,,n) dis[i]=INF;
memset(vis,,sizeof(vis));
head=tail=; q[tail++]=s;
vis[s]=; dis[s]=;
while(head!=tail) {
int u=q[head++]; vis[u]=;
for(int i=;i<g[u].size();i++) {
int v=g[u][i].v;
if(dis[v]>dis[u]+g[u][i].t-p*g[u][i].s) {
dis[v]=dis[u]+g[u][i].t-p*g[u][i].s;
if(v==t&&dis[v]<eps) return ;
if(!vis[v])
vis[v]= , q[tail++]=v;
}
}
}
return dis[t]<-eps;
} int main() {
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
read(n),read(m);
int u,v,s,t;
FOR(i,,m) {
read(u),read(v),read(t),read(s);
g[u].push_back(Edge(v,(double)t,(double)s));
}
read(m1),read(n1);
FOR(i,,n1) {
double L=,R=,M;
while((double)R-L>1e-) {
M=(L+R)*0.5;
if(spfa(n,i,M)) R=M; else L=M;
}
if(dis[i]==INF) val[i]=INF; else val[i]=(L+R)*0.5;
}
dc.init(n1+);
int S=,T=n1+;
FOR(i,,m1) {
read(u),read(v);
if(v&) swap(u,v);
if(val[u]==INF&&val[v]==INF) {
puts("-1"); return ;
}
dc.AddEdge(u,v,INF);
}
FOR(i,,n1) {
if(i&) dc.AddEdge(S,i,val[i]);
else dc.AddEdge(i,T,val[i]);
}
printf("%.1lf",dc.Maxflow(S,T));
return ;
}
ps:原来我大SD也有如此放(si)荡(xiang)不(wo)羁(chuo)的出题人
spfa的队列要开大一点!spfa的队列要开大一点!spfa的队列要开大一点!
难得一次不用STL,你就wa给我看<_<
bzoj 2285 [Sdoi2011]保密(二分,spfa + 最大流)的更多相关文章
- BZOJ 2285 [Sdoi2011]保密
题解: 求比值用分数规划,单个求太慢了套整体二分 然后求二分图最小割 // luogu-judger-enable-o2 #include<iostream> #include<cs ...
- bzoj 1305: [CQOI2009]dance 二分+網絡流判定
1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 1340 Solved: 581[Submit][Sta ...
- bzoj 3993 星际战争 - 二分答案 - 最大流
3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值减少到0或者 ...
- Bzoj 2282: [Sdoi2011]消防(二分答案)
2282: [Sdoi2011]消防 Time Limit: 10 Sec Memory Limit: 512 MB Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条 ...
- bzoj 3130 [Sdoi2013]费用流(二分,最大流)
Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识. 最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络 ...
- BZOJ 2406 矩阵(二分+有源汇上下界可行流)
题意 题解 二分答案+可行流判断. 模板题. CODE #include <cstdio> #include <cstring> #include <algorithm& ...
- 【BZOJ2285】[SDOI2011]保密(分数规划,网络流)
[BZOJ2285][SDOI2011]保密(分数规划,网络流) 题面 BZOJ 洛谷 题解 首先先读懂题目到底在干什么. 发现要求的是一个比值的最小值,二分这个最小值\(k\),把边权转换成\(t- ...
- 【BZOJ2245】[SDOI2011]工作安排(费用流)
[BZOJ2245][SDOI2011]工作安排(费用流) 题面 BZOJ 洛谷 题解 裸的费用流吧. 不需要拆点,只需要连边就好了,保证了\(W_j<W_{j+1}\). #include&l ...
- BZOJ 3876 支线剧情 | 有下界费用流
BZOJ 3876 支线剧情 | 有下界费用流 题意 这题题面搞得我看了半天没看懂--是这样的,原题中的"剧情"指的是边,"剧情点"指的才是点. 题面翻译过来大 ...
随机推荐
- 【python】Python 3 +pycharm中文支持解决方案
使用环境:window10 + python 3.5.1 方法:在代码前端增加代码:# -*-coding:gbk-*-
- MVC+EF 随笔小计——NuGet程序包管理
安装EF 打开 工具-库程序包管理器-程序包管理器控制台 输入 install-package entityframework 去MSDN上查看下EF的架构图:http://msdn.microsof ...
- App新版本提醒
童鞋们是否遇过在使用app的时候出现有新版本更新跳转到苹果商店的提示呢? github中有一个三方框架 Harpy 完美实现了这一功能! demo时刻 我的github - Harpy
- winform 项目获取app.config 中appSettings节点数据
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...
- lettcode-102:Binary Tree Level Order Traversal (Java)
Binary Tree Level Order Traversal 二叉树的层序遍历 两种方式: 1.用两个queue交替表示每一层的节点 2.用两个node,一个表示当前层的最后一个节点,一个表示下 ...
- 基于android混合开发的JsBridge技术学习
1.无JsBridge. js如果要调用java(native.也说原生)方法:则java必须实现js接口供挂载在window对象上供js来执行. 这里简单的可以只调用,调用后java端什么也不做.复 ...
- oracle dblink 配置两个ip
create database link test_link connect to xx identified by xx using '(DESCRIPTION = (ADDRESS_LIST = ...
- Java中的编码
package coreJava; import javax.swing.plaf.synth.SynthSpinnerUI; public class EncodeDemo { public sta ...
- 输出排名第k的法雷级数的值;
#include<cstdio> #include<cstring> using namespace std; int k,n; void dfs(int a,int b,in ...
- 标准C++中的string类的用法总结(转)
http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的 ...