QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#56948 | #2517. Critical Structures | Sa3tElSefr# | AC ✓ | 76ms | 7708kb | C++ | 2.6kb | 2022-10-22 00:11:39 | 2022-10-22 00:11:42 |
Judging History
answer
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;
const int N = 1e3 + 5;
int t, n, m;
vector<int> g[N];
int d[N], low[N], T, cnt, id[N], mx, com;
bool vis[N], vis2[N], AP[N];
stack<int> nodes;
void dfs(int node, int par) {
d[node] = low[node] = ++T;
vis[node] = true;
vis2[node] = true;
int c = 0;
nodes.push(node);
for(auto &i : g[node]) {
if(i == par)
continue;
if(!vis[i]) {
c++;
dfs(i, node);
low[node] = min(low[node], low[i]);
} else if(vis2[i])
low[node] = min(low[node], d[i]);
}
if(low[node] == d[node]) {
cnt++;
while(1) {
int cur = nodes.top();
id[cur] = cnt;
vis2[cur] = false;
nodes.pop();
if(cur == node)
break;
}
}
}
void dfsAP(int node, int par) {
d[node] = low[node] = ++T;
vis[node] = true;
int c = 0;
for(auto &i : g[node]) {
if(i == par)
continue;
if(!vis[i]) {
c++;
dfsAP(i, node);
low[node] = min(low[node], low[i]);
if(low[i] >= d[node])
AP[node] = true;
} else
low[node] = min(low[node], d[i]);
}
if(node == 1)
AP[node] = (c > 1);
}
void init() {
T = 0;
for(int i = 1;i <= n;i++) {
low[i] = d[i] = 0;
vis[i] = vis2[i] = AP[i] = 0;
}
}
pair<int, int> get(int p, int q) {
int g = __gcd(p, q);
return {p / g, q / g};
}
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> t;
while(t--) {
cin >> n >> m;
for(int i = 1;i <= n;i++)
g[i].clear();
for(int i = 0;i < m;i++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
cnt = mx = com = 0;
vector<int> edges(n + 1, 0);
init();
dfs(1, 1);
init();
dfsAP(1, 1);
int bridges = 0;
for(int i = 1;i <= n;i++) {
for(auto j : g[i]) {
if(id[i] != id[j])
bridges++;
else
edges[id[i]]++;
}
}
if(bridges)
mx = max(mx, 1);
bridges /= 2;
for(int i = 0;i < n;i++) {
if(edges[i] > 2) {
com++;
mx = max(mx, edges[i] / 2);
}
}
auto r = get(com + bridges, mx);
cout << accumulate(AP + 1, AP + n + 1, 0) << " ";
cout << bridges << " " << r.first << " " << r.second << '\n';
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 3616kb
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: 2ms
memory: 3688kb
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: 76ms
memory: 7708kb
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