• 【SDOI2015】星际战争(网络流)


    由于时间可能是小数,所以不能直接跑。

    先二分答案为 t t t

    S S S 向每个激光武器 i i i 连一条容量为 b i × t b_i imes t bi×t 的边,表示这个激光武器最多能输出多少。

    然后每个机器人向 T T T 连一条容量为 a i a_i ai 的边,表示这个机器人至少需要这么多攻击才能被摧毁。

    接着每个激光武器向每个它能攻击的机器人连一条容量为 inf ⁡ inf inf 的边。

    然后跑最大流看流量等不等于所有机器人的血量之和。

    因为时间是小数,所以二分的时候时间和机器人血量先乘上个 1 0 3 10^3 103,最后输出的时候再除就好了。

    代码:

    #include<bits/stdc++.h>
    
    #define N 55
    #define ll long long
    #define LNF 0x7fffffffffffffff
    
    using namespace std;
    
    int n,m,s,t;
    int a[N],b[N];
    int cnt=1,head[N<<1],cur[N<<1],to[(N*N+(N<<1))<<1],nxt[(N*N+(N<<1))<<1];
    int stcnt,sthead[N<<1];
    int num[N<<1];
    ll sum;
    ll c[(N*N+(N<<1))<<1],stc[(N*N+(N<<1))<<1];
    
    queue<int>q;
    
    void adde(int u,int v,ll ci)
    {
    	to[++cnt]=v;
    	c[cnt]=ci;
    	nxt[cnt]=head[u];
    	head[u]=cnt;
    }
    
    bool bfs()
    {
    	memcpy(cur,head,sizeof(cur));
    	memset(num,-1,sizeof(num));
    	num[s]=0;
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=head[u];i;i=nxt[i])
    		{
    			int v=to[i];
    			if(c[i]&&num[v]==-1)
    			{
    				num[v]=num[u]+1;
    				q.push(v);
    			}
    		}
    	}
    	return num[t]!=-1;
    }
    
    ll dfs(int u,ll minflow)
    {
    	if(!minflow||u==t) return minflow;
    	ll preflow=0,nowflow;
    	for(int i=cur[u];i;i=nxt[i])
    	{
    		cur[u]=i;
    		int v=to[i];
    		if(num[v]==num[u]+1&&(nowflow=dfs(v,min(minflow-preflow,c[i]))))
    		{
    			preflow+=nowflow;
    			c[i]-=nowflow;
    			c[i^1]+=nowflow;
    			if(!(minflow-preflow)) break;
    		}
    	}
    	return preflow;
    }
    
    ll dinic()
    {
    	ll maxflow=0;
    	while(bfs())
    		maxflow+=dfs(s,LNF);
    	return maxflow;
    }
    
    bool check(int x)
    {
    	cnt=stcnt;
    	memcpy(head,sthead,sizeof(head));
    	memcpy(c,stc,sizeof(c));
    	for(int i=1;i<=m;i++)
    	{
    		adde(s,1+i,1ll*b[i]*x);
    		adde(1+i,s,0);
    	}
    	return dinic()==sum;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	s=1,t=1+m+n+1;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]),a[i]*=1000;
    		sum+=a[i];
    		adde(1+m+i,t,a[i]);
    		adde(t,1+m+i,0);
    	}
    	for(int i=1;i<=m;i++)
    		scanf("%d",&b[i]);
    	for(int i=1;i<=m;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			int x;
    			scanf("%d",&x);
    			if(x)
    			{
    				adde(1+i,1+m+j,LNF);
    				adde(1+m+j,1+i,0);
    			}
    		}
    	}
    	stcnt=cnt;
    	memcpy(sthead,head,sizeof(sthead));
    	memcpy(stc,c,sizeof(stc));
    	int l=0,r=1000000000,ans;
    	while(l<=r)
    	{
    		int mid=(l+r)>>1;
    		if(check(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%lf
    ",1.0*ans/1000);
    	return 0;
    }
    
  • 相关阅读:
    Dockerfile文件详解
    docker-compose.yml文件
    Linux集中日志服务器rsyslog
    数据库连接池DBUtils使用
    js开关插件使用
    flask基础
    redis系列--深入哨兵集群
    Python算法基础
    redis系列--主从复制以及redis复制演进
    redis系列--redis4.0深入持久化
  • 原文地址:https://www.cnblogs.com/ez-lcw/p/14448675.html
Copyright © 2020-2023  润新知