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 支线剧情 | 有下界费用流 题意 这题题面搞得我看了半天没看懂--是这样的,原题中的"剧情"指的是边,"剧情点"指的才是点. 题面翻译过来大 ...
随机推荐
- MySQL基础学习之开始
学习MySQL数据库几个月了,从什么都不懂到现在这个地步,说实话感触很大,也感觉自己有许多不足之处.当接触MySQL的时候, 连创建一个数据表都想了很长的时间,不知道许多东西.幸亏我有一个好的老师,她 ...
- How to open .ccproj in VS2010?
Q: How to open .ccproj projects types in VS2010, ccproj file type is a Cloud project i suppose. Plea ...
- hdu 5652 India and China Origins 并查集+逆序
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652 题意:一张n*m个格子的点,0表示可走,1表示堵塞.每个节点都是四方向走.开始输入初始状态方格, ...
- NGUI系列教程三
接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...
- swfupload 上传控件的配置
第一:下载swfupload控件,点击下载: 第二,解压缩后,在项目中添加这四个文件,如图: 然后,在你的js文件中添加这段代码: /** * *定义swfupload配置文件对象 **/ var s ...
- vs2013下使用Assist X的破解方法
Assist X的破解下载:http://pan.baidu.com/s/1kTnDH23 密码:j9jp 01.安装,点击VA_X_Setup2042.exe 安装 02.破解 找到这样的目录:C: ...
- ***PHP请求服务curl以及json的解析
对于thinkphp框架,相信每一个php开发者都会有了解或者熟悉吧!前端很多都用的ajax的结合,前几天遇到了一个问题,就是请求另一个服务,也就是请求一个接口,然后对方返回一个json串,一开始对c ...
- HDU2167+状态压缩DP
状态压缩dp 详见代码 /* 状态压缩dp dp[ i ][ j ]:第i行j状态的最大和 dp[i][j] = max( dp[i-1][k]+sum[i][j] ); 题意:给定一个N*N的方格, ...
- UVA 125 Numbering Paths
题目大意:给定n条单向边,求图中任意两点的连通路径的数目.其中点是从0-输入中出现的最大的点. 可以用floyd-warshall算法或者dfs. for(int k = 0; k < n; k ...
- 调色板QPalette类用法详解(附实例、源码)
http://blog.csdn.net/rl529014/article/details/51589096