QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#721741#2517. Critical Structuresucup-team5062#AC ✓60ms23416kbC++172.0kb2024-11-07 16:44:102024-11-07 16:44:10

Judging History

你现在查看的是最新测评结果

  • [2024-11-07 16:44:10]
  • 评测
  • 测评结果:AC
  • 用时:60ms
  • 内存:23416kb
  • [2024-11-07 16:44:10]
  • 提交

answer

#include <set>
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
using namespace std;

struct edge {
	int t, id;
};

vector<vector<int> > biconnected(int N, int M, const vector<vector<edge> >& G) {
	vector<bool> vis(N, false);
	vector<int> depth(N);
	vector<edge> par(N, edge{-1, -1});
	vector<int> low(N);
	vector<vector<int> > ans;
	vector<edge> st;
	auto dfs = [&](auto& self, int x) -> void {
		vis[x] = true;
		low[x] = depth[x];
		for (edge e : G[x]) {
			if (!vis[e.t]) {
				depth[e.t] = depth[x] + 1;
				par[e.t] = edge{x, e.id};
				st.push_back(e);
				self(self, e.t);
				low[x] = min(low[x], low[e.t]);
				if (low[e.t] >= depth[x]) {
					ans.push_back(vector<int>());
					while (st.back().id != e.id) {
						ans.back().push_back(st.back().id);
						st.pop_back();
					}
					ans.back().push_back(e.id);
					st.pop_back();
				}
			} else if (depth[e.t] < depth[x] && e.id != par[x].id) {
				st.push_back(e);
				low[x] = min(low[x], depth[e.t]);
			}
		}
	};
	dfs(dfs, 0);
	return ans;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int T;
	cin >> T;
	for (int id = 1; id <= T; id++) {
		int N, M;
		cin >> N >> M;
		vector<vector<edge> > G(N);
		vector<int> A(M), B(M);
		for (int i = 0; i < M; i++) {
			cin >> A[i] >> B[i];
			A[i]--; B[i]--;
			G[A[i]].push_back(edge{B[i], i});
			G[B[i]].push_back(edge{A[i], i});
		}
		vector<vector<int> > ans = biconnected(N, M, G);
		vector<int> c(N);
		for (int i = 0; i < ans.size(); i++) {
			set<int> s;
			for (int j : ans[i]) {
				s.insert(A[j]);
				s.insert(B[j]);
			}
			for (int j : s) {
				c[j]++;
			}
		}
		int ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0;
		for (int i = 0; i < N; i++) {
			ans1 += int(c[i] >= 2);
		}
		for (int i = 0; i < ans.size(); i++) {
			ans2 += int(ans[i].size() == 1);
			ans3 += 1;
			ans4 = max(ans4, int(ans[i].size()));
		}
		cout << ans1 << ' ' << ans2 << ' ' << ans3 / gcd(ans3, ans4) << ' ' << ans4 / gcd(ans3, ans4) << endl;
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3556kb

input:

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

output:

0 0 1 6

result:

ok single line: '0 0 1 6'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3660kb

input:

1
6 7
1 2
2 3
3 1
4 5
5 6
6 4
1 4

output:

2 1 1 1

result:

ok single line: '2 1 1 1'

Test #3:

score: 0
Accepted
time: 60ms
memory: 23416kb

input:

10
6 6
1 2
2 3
3 4
4 5
5 6
6 1
5 4
1 2
2 3
3 4
4 5
5 7
1 2
1 3
3 4
4 5
5 3
1 4
1 5
13 16
1 2
1 6
1 3
1 7
3 7
4 6
4 5
5 6
5 7
7 8
8 9
7 10
10 11
12 13
10 12
10 13
10 11
1 2
2 3
2 4
3 5
4 5
4 6
6 7
7 8
6 8
8 9
8 10
3 3
1 2
2 3
3 1
44 66
1 5
1 12
1 33
2 27
2 31
2 32
2 35
2 37
2 40
3 6
3 30
3 44
4 20
4 ...

output:

0 0 1 6
3 4 4 1
1 1 1 3
4 5 7 8
4 4 3 2
0 0 1 3
8 9 10 57
0 0 1 499500
2 2 3 1777
108 112 113 1531

result:

ok 10 lines