【DFS】Gym

就按照题意建出有向图来(n个点,2n-2条边),然后从按随便一个rating排序,从最后一个开始dfs,用vis数组防止重复访问,因为每次之前的肯定能访问之后的(及之后的能访问的),所以不会有重复。就行了。

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100010
int a[N],b[N],A[N],n,B[N],sum;
bool cmp(const int &a,const int &b)
{
	return A[a]>A[b];
}
bool cm2(const int &a,const int &b)
{
	return B[a]>B[b];
}
int e,v[N<<1],next[N<<1],first[N];
void AddEdge(int U,int V)
{
	v[++e]=V;
	next[e]=first[U];
	first[U]=e;
}
bool vis[N];
void dfs(int U)
{
	++sum;
	vis[U]=1;
	for(int i=first[U];i;i=next[i])
	  if(!vis[v[i]])
	    dfs(v[i]);
}
int anss[N];
int main()
{
	freopen("codecoder.in","r",stdin);
	freopen("codecoder.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	  scanf("%d%d",&A[i],&B[i]);
	for(int i=1;i<=n;++i)
	  a[i]=b[i]=i;
	sort(a+1,a+n+1,cmp);
	sort(b+1,b+n+1,cm2);
	for(int i=1;i<n;++i)
	  AddEdge(a[i],a[i+1]);
	for(int i=1;i<n;++i)
	  AddEdge(b[i],b[i+1]);
	for(int i=n;i>=1;--i)
	  {
	  	if(!vis[a[i]])
	  	  dfs(a[i]);
	  	anss[a[i]]=sum-1;
	  }
	for(int i=1;i<=n;++i)
	  printf("%d
",anss[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/6352137.html