山东省第二届aThe Largest SCC(强连通分量)

                                                   The Largest SCC

                                                                       1000 ms       65536 KiB
                                                               Accepted/Submissions: 3/8 (37.50%)

Description

Consider a directed graph with N (1 <= N <= 1000) vertices and M (0 <= M <= 20000) edges. The edges are numbered from 1 to M and the vertices are numbered from 1 to N. Now I will make ONE edge bidirectional, and you are to tell me the number of vertices of the largest strong connected components in the new graph.The largest strong connected components is the strong connected components which has the most vertices. After the operation, I will change the edge back. There will be up to Q (1 <= Q <= 20000) such queries.

Input

 At the firest of the input comes an integer t, indicates the testcases to follow. The first line of each case contains three numbers N, M and Q. Then there will be M lines, each of them contains two numbers a,b (a! = b; 1 <= a; b <= N) means there is a directed edge between a and b. The last of each case contains Q lines, each of them contains one integer q, means the edge numbered q will be change to bidirectional. There will not be duplicated edges.

Output

 For every query, output one line contains only one integer number, which is the number of vertices of the biggest strong connected components.

Sample

Input

Copy1
5 4 2
1 2
2 3
1 3
4 1
1
3

Output

Copy2
3

    需要注意的是之前数据的保存和恢复。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 50005;
const int maxm = 50005;
const int inf = 0x3f3f3f3f;
int tmaxn, remaxn;
struct edge {
	int u, v, ne;
}ed[maxm];
int head[maxn], cnt;
int low[maxn], dfn[maxn], stack[maxn], belong[maxn];//belong存的是1到n的归属
int indexn, top; int scc;//强连通分量的个数;
int flag = 0;
bool instack[maxn]; int sum[maxn];
void add(int u, int v) {
	ed[cnt].v = v; ed[cnt].ne = head[u];
	ed[cnt].u = u;head[u] = cnt++;
}
void tarjan(int u) {
//	cout << u << endl;
	int v;
	low[u] = dfn[u] = ++indexn;
	stack[top++] = u;
	instack[u] = 1;
	for (int s = head[u]; ~s; s = ed[s].ne) {
		v = ed[s].v;
		if (!dfn[v]) {
		//	cout << u << " go " << v << endl;
			tarjan(v);
			if (low[u] > low[v])low[u] = low[v];
		}
		else if (instack[v] && low[u] > dfn[v])
			low[u] = dfn[v];
	}
	if (low[u] == dfn[u]) {
		scc++;
		do {
			v = stack[--top];
			instack[v] = 0;
			if (!flag)
				belong[v] = scc;
			sum[scc]++;
			tmaxn = max(tmaxn, sum[scc]);
		} while (v != u);
	}
}
void solve(int n) {
	memset(dfn, 0, sizeof(dfn));
	memset(instack, 0, sizeof(instack));
	memset(sum, 0, sizeof(sum));
	indexn = scc = top = 0;
	for (int s = 1; s <= n; s++)
		if (!dfn[s])
			tarjan(s);
}
void init() {
	cnt = 0;
	memset(head, -1, sizeof(head));
}
int main() {
	int te;
	ios::sync_with_stdio(0);
	cin >> te;
	while (te--) {
		flag = 0;
		int n, m, q;
		cin >> n >> m >> q;
		init();
		while (m--) {
			int a, b;
			cin >> a >> b;
			add(a, b);
		}	
		tmaxn = 0, remaxn;
		solve(n);
		flag = 1;
		remaxn = tmaxn;
		while (q--) {
			int a; cin >> a; a--;
			int u = ed[a].v, v = ed[a].u;
			if (belong[u] == belong[v]) {
				cout << tmaxn << "\n";
				continue;
			}
			add(u, v);
			indexn = top = 0;
			memset(dfn, 0, sizeof(dfn));
			tarjan(v);
			cout << tmaxn << "\n";
			tmaxn = remaxn;
			head[u] = ed[--cnt].ne;
		}
	}
	return 0;
}

 

全部评论

相关推荐

萧索X:写篮球联赛干嘛,陪老板打篮球吗。还有实习经历要写自己所在岗位具体完成什么工作,自己的任务具体完成了什么需求,给公司带来了哪些量化增长
点赞 评论 收藏
分享
2025-12-18 22:04
已编辑
杭州电子科技大学 Java
程序员花海:技能放最后 另外这两个项目写的太简单了 没有业务没有技术栈 这种简历连HR都过不了
实习简历求拷打
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务