zoukankan      html  css  js  c++  java
  • 【BZOJ5037】[Jsoi2014]电信网络 最大权闭合图

    【BZOJ5037】[Jsoi2014]电信网络

    Description

    JYY创建的电信公司,垄断着整个JSOI王国的电信网络。JYY在JSOI王国里建造了很多的通信基站。目前所有的基站都是使用2G网络系统的。而现在3G时代已经到来了,JYY在思考,要不要把一些基站升级成3G网络的呢?JSOI王国可以被看作为一个无穷大的二维平面,JYY一共建造了N个通信基站,第i个基站的坐标是(Xi,Yi)。每个基站有一个通信范围Ri。第i号基站会向所有到其距离不超过Ri的基站发送信息。每个基站升级到3G网络都会有一个收益Si,这个收益可能是正数(比如基站附近有个大城市,用户很多,赚的流量费也就很多了),也可能是负数(比如基站周围市场不佳,收益不能填补升级基站本身的投资)。此外,由于原有的使用2G网络系统的基站无法解析从升级成3G网络系统的基站所发来的信息(但是升级之后的基站是可以解析未升级基站发来的信息的),所以,JYY必须使得,在升级工作全部完成之后,所有使用3G网络的基站,其通信范围内的基站,也都是使用3G网络的。由于基站数量很多,你可以帮助JYY计算一下,他通过升级基站,最多能获得的收益是多少吗?

    Input

    第一行一个整数N;
    接下来N行,每行4个整数,Xi,Yi,Ri,Si,表示处在(Xi,Yi)的基站的通信范围是Ri,升级可以获得的收益是Si。
    数据满足任意两个基站的坐标不同。
    1≤N≤500,1≤Ri≤20000,|Xi|,|Yi|,|Si|≤10^4。

    Output

     输出一行一个整数,表示可以获得的最大收益。

    Sample Input

    5
    0 1 7 10
    0 -1 7 10
    5 0 1 -15
    10 0 6 10
    15 1 2 -20

    Sample Output

    5
    【样例说明】
    我们可以将前三座基站升级成 3G 网络,以获得最佳收益。

    题解:显然是一个最大权闭合图的模型,直接上建图方法:

    1.S->所有正权的点 容量:该点权权值
    2.所有负权的点->T 容量:该点权值相反数
    3.点>所有它能发射到的点 容量:inf

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <queue>
    using namespace std;
    int n,cnt,ans,S,T;
    int x[510],y[510],r[510],s[510];
    int to[1000000],next[1000000],val[1000000],head[510],d[510];
    queue<int> q;
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void add(int a,int b,int c)
    {
    	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
    	to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
    }
    int dfs(int x,int mf)
    {
    	if(x==T)	return mf;
    	int i,k,temp=mf;
    	for(i=head[x];i!=-1;i=next[i])
    	{
    		if(d[to[i]]==d[x]+1&&val[i])
    		{
    			k=dfs(to[i],min(val[i],temp));
    			if(!k)	d[to[i]]=0;
    			val[i]-=k,val[i^1]+=k,temp-=k;
    			if(!temp)	break;
    		}
    	}
    	return mf-temp;
    }
    int bfs()
    {
    	while(!q.empty())	q.pop();
    	memset(d,0,sizeof(d));
    	q.push(S),d[S]=1;
    	int i,u;
    	while(!q.empty())
    	{
    		u=q.front(),q.pop();
    		for(i=head[u];i!=-1;i=next[i])
    		{
    			if(!d[to[i]]&&val[i])
    			{
    				d[to[i]]=d[u]+1;
    				if(to[i]==T)	return 1;
    				q.push(to[i]);
    			}
    		}
    	}
    	return 0;
    }
    int main()
    {
    	n=rd(),S=0,T=n+1;
    	int i,j;
    	memset(head,-1,sizeof(head));
    	for(i=1;i<=n;i++)
    	{
    		x[i]=rd(),y[i]=rd(),r[i]=rd(),s[i]=rd();
    		if(s[i]>0)	ans+=s[i],add(S,i,s[i]);
    		else	add(i,T,-s[i]);
    	}
    	for(i=1;i<=n;i++)
    	{
    		for(j=1;j<=n;j++)	if(i!=j&&(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])<=r[i]*r[i])	add(i,j,1<<30);
    	}
    	while(bfs())	ans-=dfs(S,1<<30);
    	printf("%d",ans);
    	return 0;
    }
  • 相关阅读:
    sws_getContext函数参数介绍
    FFmpeg 将YUV数据转RGB
    信号槽同步
    git stash
    Qt 事件
    Qt 信号与槽函数
    微信红包的算法实现
    Python正则表达式中的re.S
    hive函数 -- split 字符串分割函数
    python None与Null
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7500343.html
Copyright © 2011-2022 走看看