2020ByteDance Camp网络选拔赛 F Interactive Valuer

艹 啊,不会L啊,打了一半去南京热身赛了,队友后面的题也不会。。。前面有没有好哥哥放弃一下名额啊。。。

这题就是大模拟就完了,因为可能有环,那我们就强连通分量先缩点,然后resnum记录每个testcase还有多少没确定的subtask需要测他

如果一个subtask中的一个点没过,那么就dfs所有依赖于他的全部标记为失败,并把所有要问的测试点resnum[x]--

每次找到离now最近的还需要测的点也就是resnum[]>0

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

const int maxl=1010;

int n,t,cnt,tot;
int len[maxl],s[maxl],ns[maxl],resnum[maxl],ac[maxl];
vector<int> a[maxl],na[maxl],e[maxl],ne[maxl],dy[maxl];
bool no[maxl],ain[maxl][maxl],g[maxl][maxl];
int ind,ff,top;
int dfn[maxl],low[maxl],sta[maxl],f[maxl]; 
bool in[maxl];

inline void tarjan(int u)
{
	int v;sta[++top]=u;in[u]=true;	
	dfn[u]=low[u]=++ind;
	for(int v:e[u])
	if(!dfn[v])
	{
		tarjan(v);
		if(low[v]<low[u])
			low[u]=low[v];
	}
	else if(in[v] && dfn[v]<low[u])
		low[u]=dfn[v];
	if(dfn[u]==low[u])
	{
		ff++;
		do
		{
			v=sta[top];sta[top--]=0;
			f[v]=ff;
			in[v]=false;
		}while(v!=u);
	}
}

inline void prework()
{
	//cin.tie(nullptr);cout.tie(nullptr);
	//cin>>n>>t;
	scanf("%d%d",&n,&t);
	for(int i=1;i<=n;i++)
	{
		//cin>>s[i];cin>>len[i];
		scanf("%d%d",&s[i],&len[i]);
		for(int j=1;j<=len[i];j++)
		{
			int x;//cin>>x;
			scanf("%d",&x);
			a[i].push_back(x);
		}
	}
	for(int i=1;i<=n;i++)
	{
		int d,u;//cin>>d;
		scanf("%d",&d);
		for(int j=1;j<=d;j++)
		{
			//cin>>u;
			scanf("%d",&u);
			if(u!=i)
				e[u].push_back(i);
		}
	}
	for(int i=1;i<=n;i++)
	if(!dfn[i])
		tarjan(i);
	for(int i=1;i<=n;i++)
	{
		ns[f[i]]+=s[i];
		for(int x:a[i])
		if(!ain[f[i]][x])
		{
			na[f[i]].push_back(x);
			ain[f[i]][x]=true;
		}
		for(int v:e[i])
		if(f[i]!=f[v] && !g[f[i]][f[v]])
		{
			ne[f[i]].push_back(f[v]);
			g[f[i]][f[v]]=true;
		}
	}
	for(int i=1;i<=ff;i++)
	{
		sort(na[i].begin(),na[i].end());
		no[i]=false;
		for(int x:na[i])
		{
			resnum[x]++;
			dy[x].push_back(i);
		}
	}
}

inline void dfs(int u)
{
	no[u]=true;
	for(int x:na[u])
		resnum[x]--;
	for(int v:ne[u])
	if(!no[v])
		dfs(v);
}

inline void print()
{
	int ans=0;
	for(int i=1;i<=ff;i++)
	if(!no[i])
		ans+=ns[i];
	//cout<<ans<<'\n';
	printf("%d\n",ans);
	fflush(stdout);
}

inline void mainwork()
{
	int now=0;
	while(1)
	{
		bool flag=false;
		for(int i=now+1;i<=t;i++)
		if(resnum[i]>0)
		{
			//cout<<-(i-now)<<'\n';
			printf("-%d\n",i-now);
			fflush(stdout);
			flag=true;
			now=i;
			break;
		}
		if(!flag)
		{
			print();
			return;
		}
		//cin>>ac[now];
		scanf("%d",&ac[now]);
		if(!ac[now])
		{
			for(int sub:dy[now])
			if(!no[sub])
				dfs(sub);
		}
	}
}

int main()
{
	prework();
	mainwork();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/111411339