Submission #5423

# Submission time Handle Problem Language Result Execution time Memory
5423 2014-05-01T14:37:59 Z Qwaz Special graph (IZhO13_specialg) C++
Compilation error
0 ms 0 KB
#include <cstdio>
#include <vector>

using namespace std;
const int MAX = 100020, BIT_MAX = 17;

int n, to[MAX], numQuery, qType[MAX], qA[MAX], qB[MAX];
vector < int > children[MAX];

void input(){
	scanf("%d", &n);

	int i;
	for(i = 1; i<=n; i++){
		scanf("%d", &to[i]);
		children[to[i]].push_back(i);
	}

	scanf("%d", &numQuery);
	for(i = 0; i<numQuery; i++){
		scanf("%d%d", &qType[i], &qA[i]);
		if(qType[i] == 2) scanf("%d", &qB[i]);
	}
}

int visited[MAX], cFull, cycleNum[MAX], cycleOrder[MAX], cycleSize[MAX];

int findCycle(int now, int visitNum){
	visited[now] = visitNum;

	if(visited[to[now]] == 0){
		int t = findCycle(to[now], visitNum);

		if(t){
			cycleNum[now] = cFull;
			cycleOrder[now] = cycleOrder[to[now]]+1;
		} else {
			cycleNum[now] = -abs(cycleNum[to[now]]);
			cycleOrder[now] = cycleOrder[to[now]];
		}

		if(now == t) return 0;
		else return t;
	} else if(visited[to[now]] == visitNum){
		cycleNum[now] = ++cFull;
		cycleOrder[now] = 1;
		return to[now];
	} else {
		cycleNum[now] = -abs(cycleNum[to[now]]);
		cycleOrder[now] = cycleOrder[to[now]];
		return 0;
	}
}

int depth[MAX], p[20][MAX];

void calcDepth(int now){
	int i;
	for(i = 0; i<children[now].size(); i++){
		int nextNum = children[now][i];
		depth[nextNum] = depth[now]+1;
		calcDepth(nextNum);
	}
}

void init(){
	int i, v = 1;
	for(i = 1; i<=n; i++){
		if(visited[i] == 0)
			findCycle(i, v++);
	}

	for(i = 1; i<=n; i++){
		if(cycleNum[i] < 0){
			if(cycleNum[to[i]] == cycleNum[i]) p[0][i] = to[i];
			else {
				p[0][i] = i;
				calcDepth(i);
			}
		} else {
			cycleSize[cycleNum[i]]++;
			p[0][i] = i;
		}
	}

	int lvl = 1;
	for(lvl = 1; lvl<=BIT_MAX; lvl++){
		for(i = 1; i<=n; i++)
			p[lvl][i] = p[lvl-1][p[lvl-1][i]];
	}
}

int uf[MAX], firstCut[MAX];
bool cycleOK[MAX];

int getParent(int num){
	if(uf[num] == num) return num;
	return uf[num] = getParent(uf[num]);
}

void link(int a, int b){
	if(getParent(a) == getParent(b)){
		cycleOK[cycleNum[a]] = 1;
	} else {
		uf[getParent(a)] = getParent(b);
	}
}

void cut(){
	int i, tNext[MAX];
	for(i = 1; i<=n; i++){
		tNext[i] = to[i];
		uf[i] = i;
	}

	for(i = 0; i<numQuery; i++){
		if(qType[i] == 1){
			if(cycleNum[qA[i]] > 0 && firstCut[cycleNum[qA[i]]] == 0)
				firstCut[cycleNum[qA[i]]] = cycleOrder[qA[i]];
			tNext[qA[i]] = 0;
		}
	}

	for(i = 1; i<=n; i++){
		if(tNext[i]){
			link(i, tNext[i]);
		}
	}
}

int cycleDist(int f, int s){
	int cn = cycleNum[f];
	if(cycleOK[cn] ||
	   (cycleOrder[f] > cycleOrder[s]
	   ? !(cycleOrder[f] >= firstCut[cn] && firstCut[cn] > cycleOrder[s])
	   : !(cycleOrder[f] >= firstCut[cn] || firstCut[cn] > cycleOrder[s]))){
		int cs = cycleSize[cn];
		return (cycleOrder[f]-cycleOrder[s]+cs) % cs;
	} else return -1;
}

int res[MAX];

void solve(){
	int i;
	for(i = numQuery-1; i>=0; i--){
		if(qType[i] == 1){
			link(qA[i], to[qA[i]]);
		} else {
			res[i] = -1;

			int f = qA[i], s = qB[i];
			if(f == s) res[i] = 0;
			else if(getParent(f) == getParent(s)){
				if(cycleNum[s] > 0){
					if(cycleNum[f] == cycleNum[s]){
						//사이클 -> 사이클
						res[i] = cycleDist(f, s);
					} else if(cycleNum[f] == -cycleNum[s]){
						//트리 -> 사이클
						int t = cycleDist(to[p[BIT_MAX][f]], s);
						if(t != -1)
							res[i] = depth[f]+1 + t;
					}
				} else {
					if(cycleNum[f] == cycleNum[s] && cycleOrder[f] == cycleOrder[s] && depth[s] < depth[f]){
						//트리 -> 트리
						int dist = depth[f]-depth[s];

						int t;
						for(t = 0; t<=BIT_MAX; t++){
							if(dist & (1<<t)){
								f = p[t][f];
							}
						}

						if(f == s)
							res[i] = dist;
					}
				}
			}
		}
	}

	for(i = 0; i<numQuery; i++){
		if(qType[i] == 2){
			printf("%d\n", res[i]);
		}
	}
}

int main(){
	input();

	init();
	cut();
	
	solve();

	return 0;
}

Compilation message

specialg.cpp: In function 'int findCycle(int, int)':
specialg.cpp:38:42: error: 'abs' was not declared in this scope
specialg.cpp:49:41: error: 'abs' was not declared in this scope
specialg.cpp: In function 'void calcDepth(int)':
specialg.cpp:59:34: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
specialg.cpp: In function 'void input()':
specialg.cpp:11:17: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
specialg.cpp:15:22: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
specialg.cpp:19:24: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
specialg.cpp:21:35: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
specialg.cpp:22:40: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]