2013 TCO Algorithm Round 2B - Division I, Level Two ScotlandYard

这道题给出了解决一类问题的思路。我们把一个人可能在的所有点看成一个集合,把一个集合看成一个点,考虑集合之间的转移关系,在这一张新图上考虑问题。官方题解上说了,只要考虑所有两个点够成的集合和一个点构成的集合就可以了。因为我们并不去关注一个集合里面有哪些点,而是去关注这个集合里是不是只有个点。而且一个大的集合必然可以由两个两个的集合拼起来构成,所以所有两两的集合和一个点的集合足以表征所有集合的性质。剩下的问题就迎刃而解了。

#include 
#define maxn 10009
using namespace std;
vectorG[maxn];
int low[maxn],dfn[maxn],stk[maxn],in[maxn],top,bcnt,id[109][109],dfs_time,d[maxn];
int n,N;
void tarjan(int u)
{
	dfn[u]=low[u]=++dfs_time;
	stk[++top]=u;
	in[u]=1;
	for(int i=0;i<(int)G[u].size();i++)
	{
		int v=G[u][i];
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(in[v])
		{
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u])
	{
		bcnt++;
		int x;
		do
		{
			x=stk[top--];
			in[x]=0;
		}while(x!=u);
	}
}
bool solve(int i,int j,vector &a)
{
	vectortmp;
	for(int k=0;k A, vector  B, vector  C)
	{
		N=A.size();
		n=N*(N-1)/2+N;
		int cur=N;
		for(int i=0;i


你可能感兴趣的:(图论)