您的位置:首页 > 理论基础 > 计算机网络

bzoj3993 [SDOI2015]星际战争 二分答案+网络流检验

2017-11-27 16:42 495 查看
流量分配模型、

这个题如果时间不知道的话流量是未知的,对于流量未知的网络流肯定是没法做的(没有动态借流量的网络流)

由于时间上满足连续性,就可以二分答案,然后流量确定就可以跑网络流

主要还是化静为动

注:

1、double都要写eps

2、一定注意double和int

码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define N 12000
#define inf 1000000009
queue<int>q;
int tot=-1,hou
,xia
,zhong
,yuan
,s,t,n,m,d
,i,j,lt[55][55];
double v
,l,r,a
,b
,cnt;
void jian(int a,int b,double c)
{
++tot,zhong[tot]=b,hou[tot]=yuan[a],yuan[a]=tot,v[tot]=c;
}
void jia(int a,int b,double c)
{
jian(a,b,c);
jian(b,a,0);
}
bool bfs()
{
memset(d,0x7f,sizeof(d));
for(i=1;i<=t;i++)xia[i]=yuan[i];
d[s]=0;
q.push(s);
while(!q.empty())
{
int st=q.front();
q.pop();
for(i=xia[st];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(fabs(v[i]-0)<=0.00001||d[nd]<inf)continue;
d[nd]=d[st]+1;
q.push(nd);
}
}
//cout<<d[t]<<endl;
return d[t]<inf;
}
double dfs(int o,int t,double limit)
{if(o==t||!limit)return limit;
double flow=0,f;
int i;
for(i=xia[o];i!=-1;i=hou[i])
{
xia[o]=i;int nd=zhong[i];
if(d[nd]==d[o]+1)
{f=dfs(nd,t,min(limit,v[i]));
if(fabs(f-0)>=0.00001)
{
limit-=f;
flow+=f;
v[i]-=f;
v[i^1]+=f;
}
if(fabs(limit-0)<=0.00001)break;
}
}
return flow;
}
double dinic()
{
double daan=0;
while(bfs())
{
daan+=dfs(s,t,inf);
}
return daan;
}
int main()
{
scanf("%d%d",&n,&m);
s=n+m+1;
t=n+m+2;
for(i=1;i<=n;i++)scanf("%lf",&a[i]),cnt+=a[i];
for(i=1;i<=m;i++)scanf("%lf",&b[i]);
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
{
scanf("%d",<[i][j]);
}
l=0.0001;r=1000000;
while(l+0.00001<r)
{
double mid=(l+r)/2;
memset(yuan,-1,sizeof(yuan));
tot=-1;
for(i=1;i<=m;i++)for(j=1;j<=n;j++)if(lt[i][j])jia(i,m+j,inf);
for(i=1;i<=m;i++)jia(s,i,mid*b[i]);
for(i=1;i<=n;i++)jia(m+i,t,a[i]);
if(fabs(dinic()-cnt)<=0.000001)r=mid;else l=mid+0.0001;
}
printf("%.5lf",l);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: