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 支线剧情 | 有下界费用流 题意 这题题面搞得我看了半天没看懂--是这样的,原题中的"剧情"指的是边,"剧情点"指的才是点. 题面翻译过来大 ...
随机推荐
- php使用phpmailer发送邮件
本人新手,由于要做邮件发送验证码,所以找到和搜集到这些,本人亲测完全可以用 这是163邮箱的 因为不是企业邮箱填写的账号是163的账号,但是密码是授权码 授权码的获取方式为:
- 要成为开发中最牛逼的测试,测试中最牛逼的开发。从今天起学python,写博客。--python基础学习(一)
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32Type & ...
- “0x5003eaed” 指令引用的“0x00000000”内存。该内存不能为“read”
一.问题描述与原因分析 1.问题描述 使用VC6.0,在工具栏点击“打开文件”或者“添加文件到项目”的图标时,提示如题的错误. 2.原因分析 微软的VC6.0与office2007冲突问题. 二.解决 ...
- Python之倒序访问list
我们还是用一个list按分数从高到低表示出班里的3个同学: >>> L = ['Adam', 'Lisa', 'Bart'] 这时,老师说,请分数最低的同学站出来. 要写代码完成这个 ...
- 计算器(console version)
题目描述 请用python编写一个计算器的控制台程序,支持加减乘除.乘方.括号.小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算. 输入描述 数字包括& ...
- asp.net 文件复制或删除用相对路径,File.Copy中用相对路径,巧用相对路径复制文件
再复制文件 File.Copy(Server.MapPath("被复制的文件相对路径"), Server.MapPath("目的位置相对路径"), true); ...
- CF 217 B. Berland Bingo
http://codeforces.com/contest/370/problem/B 题意 :呃,这个题我说不清楚....就是有n个人,第 i 个人手里有 mi 张牌,如果,现在主人念数,念到哪张牌 ...
- Java简单文件传输 socket简单文件传输示例
服务器端代码: import java.io.*; import java.net.*; /** * Created with IntelliJ IDEA. * User: HYY * Date: 1 ...
- [jobdu]不用加减乘除做加法
使用异或和与,模拟机器的加法.http://blog.csdn.net/htyurencaotang/article/details/11125415 #include <iostream> ...
- [wikioi]装箱问题
http://wikioi.com/problem/1014/ 01背包问题是最经典的动态规划之一,这道题目甚至是这其中还简单的一种,因为价值就是本身的重量了.本来比如,w是总重量限制,v[]是每个的 ...