记录编号 211634 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 DAGCH 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 3.727 s
提交时间 2015-12-02 22:10:40 内存使用 4.15 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int SIZEN=100010;
void getint(int &x){
	char c=0;
	for(;c<'0'||c>'9';c=getchar());
	for(x=0;'0'<=c&&c<='9';c=getchar()) x=x*10+c-'0';
}
int N,M,Q;
vector<int> c[SIZEN],ct[SIZEN];
int timer=0,fa[SIZEN];
int ufs[SIZEN],best[SIZEN],sdom[SIZEN];
int find(int x){//将x连接到路径最上端,并计算出一路上诸点的best 
	if(x==ufs[x]) return x;
	int y=find(ufs[x]);
	if(sdom[best[ufs[x]]]<sdom[best[x]]){//注意ufs[x]≠y 
		best[x]=best[ufs[x]];
	}
	return ufs[x]=y;
}
void Lengauer_Tarjan(void){
	for(int i=1;i<=N;i++) ufs[i]=best[i]=sdom[i]=i;
	for(int i=N;i>=1;i--){
		for(int j=0;j<ct[i].size();j++){
			/*对于<i的那些,find之后是它本身 
			对于>i的那些,find之后得到了它到根的最优sdom
			注意,对于第二种情况,u~v这一路上必然全大于i*/
			int u=ct[i][j];
			find(u);
			sdom[i]=min(sdom[i],sdom[best[u]]);
		}
		ufs[i]=fa[i];
	}
}
bool vis[SIZEN];
void DFS(int x){
	vis[x]=true;
	timer++;
	for(int i=0;i<c[x].size();i++){
		int u=c[x][i];
		if(!vis[u]&&u==timer+1){
			fa[u]=x;
			DFS(u);
		}
	}
}
int ans[SIZEN];
void work(void){
	timer=0;
	memset(vis,0,sizeof(vis));
	fa[1]=0;
	DFS(1);
	Lengauer_Tarjan();
	memset(ans,0,sizeof(ans));
	for(int i=2;i<=N;i++) ans[sdom[i]]++;
	int x;
	for(int i=1;i<=Q;i++){
		getint(x);
		printf("%d ",ans[x]);
	}
	printf("\n");
}
void read(void){
	getint(N);getint(M);getint(Q);
	for(int i=1;i<=N;i++) c[i].clear(),ct[i].clear();
	int a,b;
	for(int i=1;i<=M;i++){
		getint(a);
		getint(b);
		c[a].push_back(b);
		ct[b].push_back(a);
	}
	for(int i=1;i<=N;i++) sort(c[i].begin(),c[i].end());
}
int main(void){
	freopen("dagch.in","r",stdin);
	freopen("dagch.out","w",stdout);
	int T;getint(T);
	while(T--){
		read();
		work();
	}
	return 0;
}