﻿ [UPC | 山东省赛] The Largest SCC | Tarjan强连通分量瞎搞 + 状态还原

## 题目描述

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.

## 输入

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.

## 输出

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

## 样例输入

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


2
3


Code:

int n, m, q;
struct node {
int to, nex;
} e[maxn << 2];
int dfn[maxn], low[maxn], pos[maxn];
int num[maxn], vis[maxn];
int cntSCC, ans;
void init() {
cnt = dfc = cntSCC = 0;
for(int i = 1; i <= n; i++) {
pos[i] = vis[i] = 0;
}
}
void add(int u, int v) {
e[cnt].to = v;
}
stack<int> stk;
int mx,premx;
void Tarjan(int x) {
int u = x;
dfn[u] = low[u] = ++ dfc;
vis[u] = 1;
stk.push(u);
int v = e[i].to;
if(!dfn[v]) {
Tarjan(v);
low[u] = min(low[u],low[v]);
} else if(vis[v]) {
low[u] = min(low[u],dfn[v]);
}
}
int tp;
if(low[u] == dfn[u]) {
++ cntSCC;
do{
tp = stk.top();
stk.pop();
vis[tp] = 0;
if(vis[0]) pos[tp] = cntSCC;
num[cntSCC] ++;
mx = max(mx,num[cntSCC]);
}while(tp != u);
}
}
typedef pair<int,int> PII;
vector<PII> save;
void ClearStack(){
while(stk.size()) stk.pop();
}
int main() {
while(_ --) {
init();
save.clear();
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(vis,0,sizeof vis);
memset(num,0,sizeof num);
vis[0] = 1;
for(int i = 1; i <= m; i++) {
save.push_back({u,v});
}
ClearStack();
mx = 0,premx = 0;
for(int i=1; i<=n; i++) {
if(!dfn[i]) Tarjan(i);
}
premx = mx;

//		cout << mx << endl;
//		cout << premx << endl;
vis[0] = 0;
while(q --) {
int id = read - 1;
PII eg = save[id];
int u = eg.first,v = eg.second;
//			cout << u <<"  ->  " << v<< endl;
if(pos[u] == pos[v]) {
printf("%d
",mx);
continue;
}
memset(dfn,0,sizeof dfn);
//			memset(low,0,sizeof low);
dfc = 0;
ClearStack();
Tarjan(u);
printf("%d
",mx);
mx = premx;
}
}
return 0;
}