求调今天 CF 的 D 题
  • 板块题目总版
  • 楼主王熙文
  • 当前回复2
  • 已保存回复2
  • 发布时间2022/5/14 22:12
  • 上次更新2023/10/28 01:25:39
查看原帖
求调今天 CF 的 D 题
353688
王熙文楼主2022/5/14 22:12

如题,赛时过了赛后 FST WA on test 55。

思路是二分+拓扑。

#include<bits/stdc++.h>
#define int long long
using namespace std;

int n,m,k;

int a[200010];

struct edge
{
	int u,v;
} s[200010];

int tot=0,var[200010],nxt[200010],head[200010];

void add(int u,int v)
{
	var[++tot]=v;
	nxt[tot]=head[u];
	head[u]=tot;
}

int in[200010];

queue<int> q;

int maxx[200010];

bool check(int mid)
{
	memset(maxx,0,sizeof(maxx));
	tot=0; memset(head,0,sizeof(head));
	memset(in,0,sizeof(in));
	for(int i=1; i<=m; ++i)
	{
		if(a[s[i].u]<=mid && a[s[i].v]<=mid)
		{
			add(s[i].u,s[i].v);
			++in[s[i].v];
		}
	}
	int cnt=0;
	for(int i=1; i<=n; ++i)
	{
		if(a[i]<=mid && !in[i])
		{
			++cnt;
			q.push(i);
			maxx[i]=1;
			if(k==1) return 1;
		}
	}
	while(!q.empty())
	{
		int frn=q.front(); q.pop();
		for(int i=head[frn]; i; i=nxt[i])
		{
			--in[var[i]];
			maxx[var[i]]=max(maxx[var[i]],maxx[frn]+1);
			if(maxx[var[i]]>=k) return 1;
			if(in[var[i]]==0)
			{
				q.push(var[i]);
			}
		}
	}
	for(int i=1; i<=n; ++i)
	{
		if(a[i]<=mid && in[i]) return 1;
	}
	return 0;
}

signed main()
{
	cin>>n>>m>>k;
	for(int i=1; i<=n; ++i)
	{
		cin>>a[i];
	}
	for(int i=1; i<=m; ++i)
	{
		cin>>s[i].u>>s[i].v;
	}
	int l=1,r=1e9,mid,ans=-1;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	cout<<ans;
	return 0;
}

另外,这个我写出来的二分仿佛没有单调性,如果改变右端点会得到不同的答案。

2022/5/14 22:12
加载中...