[CSP-Sシミュレーション試験]:円形の依存関係(トポロジー)

トピックポータル(内部タイトル148)


入力形式

  第一の各試験点は、$ T $整数正の作用テストポイント内のデータセットの数を表します。
  次に、データの$ Tの$セットは、最初のN- $ $正の整数の各データ線は、基準セルが計算されるセルの数、N- $ $次の行、各細胞株のための文字列を表しますセル参照番号中の細胞の数の文字列表現が続く細胞数、。


出力フォーマット

  テストデータのセットごとに、循環依存関係であれば、そうでない場合は$はい$の出力、出力$ません$。


サンプル

サンプル入力:

3
1
AA13 AA13
3
B1 A1 A2
C1 B1 A1
A2 C1 A1
4
B1 A1
C1 B1 A1
D1 C1 B1 A1
E1 D1 C1 B1 A1

出力例:

はい
はい
ません


データ範囲とヒント

サンプルは説明しました:

  データの最初のセットは、$ AA13 $基準セル自体、自己ループ依存性を構成します。
  質問プレーンの例を説明する第2のデータセット。
  第3のデータセット、$ B1の$参照の参照セルの最前線にのみ各セルので$ E1 $に$ A1 $、$ C1 $ $ B1および参照$ $ A1 $、セルの値は、したがって、円形の依存関係を構成するものではありません。

データ範囲:

  データ$ 20 \%$、$ 1があります\ nはleqslant \ leqslant 10のための $は。
  データleqslant $ 1があります$ 50 \%$、\ nは\ leqslant 100のための $。
  データの別の$ 30 \%の$、最大でセルに各セル参照ください。
  データ$ \ 100%$、$ 1があります\ leqslantのn \ leqslant 30,000 $は、 細胞数は、各セルの参照が$ 10 $番目のセル(体重番号、超えていない、もはやよりも$ 10 $文字列であります、データの各セット内のセルの数は$ \ leqslant 90,000 $)を同じ番号、各テストポイント数の細胞の総数は、データの任意のセットで、各行は最初の細胞数ではなく、$ 450,000 $を超えません繰り返したが、セルの参照番号の各セルは繰り返してもよいです。


問題の解決策

形而上学を読んで、ディスクリート、再びサンプルを通るマップ、トポロジを構築!

無知な力を見て......

 

学生も、この金額の隣に発見されました。

実際、

 

$ \ RIGHTARROW $ $ = $

トピックと人々が実際にWindowsの$メイドのデータを$使用します!

ラップは、n \ $ NOILinux $の下に取り付けられており、$ Windowsの$ \ rの下にあります。

残りは裸ですが、あなたは$ tarjan $宣告リングを使用したい場合、私はあなたを停止しないでください。

時間の複雑さ:$ \シータ(m)は$($ M $は、依存関係の数を表します)。

期待はスコア:$ $ 100ポイントを。

実際のスコア:$ $ 100ポイント。


コードの時間

#include<bits/stdc++.h>
using namespace std;
unordered_map<unsigned long long,int>mp;
struct rec{int nxt,to;}e[200001];
int head[100001],cnt;
int n;
char ch[20];
int top,tot;
int du[100001];
queue<int> q;
unsigned long long hsh[500001];
unsigned long long hd[100001];
vector<unsigned long long>son[100001];
void pre_work()
{
	mp.clear();cnt=top=tot=0;
	memset(head,0,sizeof(head));
	memset(son,0,sizeof(son));
	memset(du,0,sizeof(du));
}
unsigned long long get()
{
	int len=strlen(ch+1);unsigned long long res=0;
	for(int i=1;i<=len;i++)res=res*131+ch[i]-'0';
	return res;
}
void add(int x,int y)
{
	e[++cnt].nxt=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
bool topsort()
{
	int res=0;
	for(int i=1;i<=tot;i++)if(!du[i]){q.push(i);res++;}
	while(q.size())
	{
		int x=q.front();q.pop();
		for(int i=head[x];i;i=e[i].nxt)
		{
			du[e[i].to]--;
			if(!du[e[i].to]){res++;q.push(e[i].to);}
		}
	}
	return res==tot;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		pre_work();
		for(int i=1;i<=n;i++)
		{
			scanf("%s",ch+1);
			hd[i]=get();
			hsh[++top]=hd[i];
			char c=getchar();
			while(c!='\r')
			{
				scanf("%s",ch+1);
				hsh[++top]=get();
				son[i].push_back(hsh[top]);
				c=getchar();
			}
		}
		sort(hsh+1,hsh+top+1);
		for(int i=1;i<=top;i++)if(hsh[i]!=hsh[i-1])mp[hsh[i]]=++tot;
		for(int i=1;i<=n;i++)
		{
			hd[i]=mp[hd[i]];
			for(int j=0;j<son[i].size();j++)
				son[i][j]=mp[son[i][j]];
		}
		for(int i=1;i<=n;i++)
			for(int j=0;j<son[i].size();j++)
			{add(son[i][j],hd[i]);du[hd[i]]++;}
		puts(topsort()?"No":"Yes");
	}
	return 0;
}

rp++

おすすめ

転載: www.cnblogs.com/wzc521/p/11845556.html