1 2 3 4

codefoces 22E 图论

有些题还得练练模拟的能力呀

这题一言难尽,他给的 图不是半连通子图呀,我崩溃了

要分好组,然后1给2连,2给3连,。。。。。n给1连。。

具体看代码,我写的比较捞了吧。。

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn = 2e5 + 7;
vector<int>G[maxn], G2[maxn];

void insert(int be, int en) {
	G[be].push_back(en);
}
stack<int>s;
int in[maxn];
int out[maxn];
int n;
int dfn[maxn], low[maxn], clor[maxn], ins[maxn], ans, df;

int tarjan(int x) {
	s.push(x);
	dfn[x] = low[x] = ++df;
	for (int i = 0; i < G[x].size(); i++) {
		int p = G[x][i];
		if (!dfn[p]) {
			tarjan(p);
			low[x] = min(low[x], low[p]);
		}
		else if (!clor[p]) {
			low[x] = min(low[x], dfn[p]);
		}
	}
	if (dfn[x] == low[x]) {
		ans++;
		while (1) {
			int a = s.top();
			s.pop();
			clor[a] = ans;
			ins[ans] = a;
			if (a == x) break;
		}
	}
	return 0;
}
int find() {
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) {
			tarjan(i);
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < G[i].size(); j++) {
			int be = clor[i];
			int en = clor[G[i][j]];
			if (be != en) {
				in[en]++;
				out[be]++;//出
				G2[be].push_back(en);
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		G[i].clear();
	}
	return 0;
}
int vis[maxn];

int dfs(int x) {
	for (int i = 0; i < G2[x].size(); i++) {
		int p = G2[x][i];
		dfs(p);
		vis[x] = vis[p];
	}
	return 0;
}
int list[maxn];
vector<int>cns;
int main() {

	scanf("%d", &n);
	int x;
	int y;
	for (int i = 1; i <= n ; i++) {
		scanf("%d", &x);
		G[i].push_back(x);
	
	}
	find();
	if (ans == 1) {
		printf("0\n");
		return 0;
	}
	n = ans;
	int c = 0;
	for (int i = 1; i <= n; i++) {
		if (out[i] == 0) {
			vis[i] = ++c;
			list[c] = i;
		}
	}
	for (int i = 1; i <= n; i++) {
		if (in[i] == 0) {
			dfs(i);
		}
	}

	for (int i = 1; i <= n; i++) {
		if (in[i] == 0) {
			G[vis[i]].push_back(i);
		}
	}
	for (int i = 1; i < c; i++) {
		//list[i]--->G[i+1]
		for (int j = 0; j < G[i + 1].size(); j++) {
			cns.push_back(list[i]);
			cns.push_back(G[i + 1][j]);
		}
	}
	for (int i = 0; i < G[1].size(); i++) {
		cns.push_back(list[c]);
		cns.push_back(G[1][i]);
	}
	printf("%d\n", cns.size() / 2);
	for (int i = 0; i < cns.size(); i+=2) {
		printf("%d %d\n", ins[cns[i]], ins[cns[i + 1]]);
	}
	return 0;
}

  

posted @ 2019-12-31 19:45  Lesning  阅读(142)  评论(0编辑  收藏  举报