Educational Codeforces Round 90 (Rated for Div. 2) - F. Network Coverage

题意:

\(n\) 个城市围城一圈,第 \(i\) 个城市有 \(a_i\) 个网络需求,每个城市建有一个网络站,第 \(i\) 个城市的网络站可以提供 \(b_i\) 个网络需求;且 第 \(i\) 个城市的网络站只能提供需求给第 \(i\)\(i+1\) 个城市 \((n+1=1)\),问是否存在合理分配使得所有城市的所有需求都被满足

分析:

围成一圈,所以只要确定一个网络站的分配,就可以贪心判断是否有解;考虑城市 \(i\) 中网络站对需求的分配 \(k\) (即网络站 \(i\) 对城市 \(i\) 的分配):

  1. 如果 \(k\) 过大,那么后面就会造成断流,即某个城市得不到足够的分配;
  2. 如果 \(k\) 过小,后面不会有断流,但网络站 \(i-1\) 就没有足够的资源分配给城市 \(i\) ,使得城市 \(i\) 的需求得到满足,我们设这个资源为 \(c\),即 \(k+c<a_i\)

所以对于第 \(i\) 个城市,有解的分配 \(k\) 实际上是一个连续的区间 \([l,r]\) ,而在这个范围内,\(k\)\(-1\) ,那么 \(c\) 至多 \(+1\) ,因为如果中间产生满流了,那么此时 \(k\) 再怎么减小,\(c\) 也不变;所以我们可以二分,在 \(c>=0\) 的情况下,找到最大的 \(k\)

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define frep(i,a,b) for(int i=a;i>=b;i--)
const int N = 1E6+10;
int a[N],b[N],n;

int check(int M)
{
	int pre=b[1]-M;
	rep(i,2,n)
	{
		pre=min(pre,a[i]); 
		pre+=b[i];
		pre-=a[i];
		if(pre<0) return -1;
	}
	return pre;
}

int main()
{
	//freopen("1.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	
    int t; cin>>t;
	while(t--)
	{
		cin>>n;
		rep(i,1,n)cin>>a[i];
		rep(i,1,n)cin>>b[i];
		
		int L=0,R=min(b[1],a[1]);
		while(L<=R)
		{
			int M=(L+R)>>1;
			if(check(M)>=0) L=M+1;
			else R=M-1; 
		}
		if(R>=0&&R+check(R)>=a[1]) cout<<"YES";
		else cout<<"NO";
		cout<<endl; 
	}	
} 

猜你喜欢

转载自www.cnblogs.com/17134h/p/13200331.html