forked from mpfeifer1/Kattis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathouting.cpp
115 lines (94 loc) · 2.23 KB
/
outing.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <bits/stdc++.h>
using namespace std;
int find(vector<int>& d, int a) {
if(d[a] < 0) return a;
return d[a] = find(d, d[a]);
}
void join(vector<int>& d, int a, int b) {
a = find(d, a);
b = find(d, b);
if(a == b) return;
d[b] += d[a];
d[a] = b;
}
int size(vector<int>& d, int a) {
a = find(d, a);
return -d[a];
}
// Returns {node,dist}
pair<int,int> bfs(vector<vector<int>>& adj, int start) {
map<int,int> dist;
queue<int> q;
dist[start] = 0;
q.push(start);
int bestdist = 0;
int bestidx = start;
while(!q.empty()) {
int curr = q.front();
q.pop();
for(auto next : adj[curr]) {
if(dist.count(next) == 0) {
dist[next] = dist[curr] + 1;
if(dist[next] > bestdist) {
bestdist = dist[next];
bestidx = next;
}
q.push(next);
}
}
}
return {bestidx, bestdist};
}
int findcycle(vector<vector<int>>& adj, int start) {
pair<int,int> p1 = bfs(adj,start);
pair<int,int> p2 = bfs(adj, p1.first);
return 1 + p2.second;
}
void add(vector<bool>& can, pair<int,int> p) {
vector<int> next(can.size()*2+2, false);
for(int i = 0; i < can.size(); i++) {
if(can[i]) {
next[i+p.first]++;
next[i+p.second+1]--;
}
}
int total = 0;
for(int i = 0; i < can.size(); i++) {
total += next[i];
if(total > 0) {
can[i] = true;
}
}
}
int main() {
int n, m;
cin >> n >> m;
vector<int> d(n, -1);
vector<vector<int>> adj(n);
for(int i = 0; i < n; i++) {
int t;
cin >> t;
t--;
join(d, i, t);
adj[i].push_back(t);
}
vector<pair<int,int>> values;
// For each representative, find cycle size
for(int i = 0; i < n; i++) {
if(d[i] < 0) {
int cycle = findcycle(adj, i);
values.push_back({cycle, size(d,i)});
}
}
vector<bool> can(n+1,false);
can[0] = true;
for(auto i : values) {
add(can, i);
}
for(int i = m; i >= 0; i--) {
if(can[i]) {
cout << i << endl;
break;
}
}
}