Skip to content

Commit 155f150

Browse files
committed
day25
1 parent 3753596 commit 155f150

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

2023/day25/day25_1.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
unordered_map<string, size_t> name2id;
5+
size_t n = 0;
6+
size_t get_id(string& s)
7+
{
8+
if (name2id.find(s) == name2id.end()) {
9+
name2id[s] = n++;
10+
}
11+
return name2id[s];
12+
}
13+
14+
bool bfs(vector<vector<size_t>>& residual_graph, vector<size_t>& parent, size_t source, size_t sink)
15+
{
16+
size_t V = residual_graph.size();
17+
vector<bool> visited(V, false);
18+
19+
queue<size_t> q;
20+
q.push(source);
21+
visited[source] = true;
22+
parent[source] = -1;
23+
24+
while (!q.empty()) {
25+
size_t u = q.front();
26+
q.pop();
27+
28+
for (size_t v = 0; v < V; v++) {
29+
if (!visited[v] && residual_graph[u][v] > 0) {
30+
q.push(v);
31+
parent[v] = u;
32+
visited[v] = true;
33+
}
34+
}
35+
}
36+
37+
return visited[sink];
38+
}
39+
40+
void dfs(vector<vector<size_t>>& residual_graph, vector<bool>& visited, size_t u)
41+
{
42+
visited[u] = true;
43+
size_t V = residual_graph.size();
44+
45+
for (size_t v = 0; v < V; v++) {
46+
if (!visited[v] && residual_graph[u][v] > 0) {
47+
dfs(residual_graph, visited, v);
48+
}
49+
}
50+
}
51+
52+
set<pair<size_t, size_t>> min_cut(vector<vector<size_t>>& graph, size_t source, size_t sink)
53+
{
54+
size_t V = graph.size();
55+
vector<vector<size_t>> residual_graph(V, vector<size_t>(V, 0));
56+
vector<size_t> parent(V, 0);
57+
58+
for (size_t u = 0; u < V; u++) {
59+
for (size_t v : graph[u]) {
60+
residual_graph[u][v] = 1;
61+
}
62+
}
63+
64+
size_t max_flow = 0;
65+
66+
while (bfs(residual_graph, parent, source, sink)) {
67+
size_t path_flow = INT_MAX;
68+
for (size_t v = sink; v != source; v = parent[v]) {
69+
size_t u = parent[v];
70+
path_flow = min(path_flow, residual_graph[u][v]);
71+
}
72+
73+
for (size_t v = sink; v != source; v = parent[v]) {
74+
size_t u = parent[v];
75+
residual_graph[u][v] -= path_flow;
76+
residual_graph[v][u] += path_flow;
77+
}
78+
79+
max_flow += path_flow;
80+
}
81+
82+
vector<bool> visited(V, false);
83+
dfs(residual_graph, visited, source);
84+
85+
set<pair<size_t, size_t>> cut_edges;
86+
for (size_t u = 0; u < V; u++) {
87+
for (size_t v = 0; v < V; v++) {
88+
if (visited[u] && !visited[v] && find(graph[u].begin(), graph[u].end(), v) != graph[u].end()) {
89+
cut_edges.emplace(u, v);
90+
}
91+
}
92+
}
93+
94+
return cut_edges;
95+
}
96+
97+
size_t count_connected(vector<vector<size_t>>& graph, size_t node, vector<bool>& vis, set<pair<size_t, size_t>>& cut)
98+
{
99+
if (vis[node]) return 0;
100+
vis[node] = true;
101+
102+
size_t res = 1;
103+
for (size_t next : graph[node]) {
104+
if (cut.find({node, next}) == cut.end()) {
105+
res += count_connected(graph, next, vis, cut);
106+
}
107+
}
108+
109+
return res;
110+
}
111+
112+
int main()
113+
{
114+
vector<vector<size_t>> graph;
115+
string line;
116+
117+
while (getline(cin, line)) {
118+
stringstream ss(line);
119+
string from, to;
120+
ss >> from;
121+
from.pop_back();
122+
size_t from_id = get_id(from);
123+
if (graph.size() <= from_id) {
124+
graph.resize(from_id + 1);
125+
}
126+
127+
while (ss >> to) {
128+
size_t to_id = get_id(to);
129+
if (graph.size() <= to_id) {
130+
graph.resize(to_id + 1);
131+
}
132+
graph[from_id].push_back(to_id);
133+
graph[to_id].push_back(from_id);
134+
}
135+
}
136+
137+
set<pair<size_t, size_t>> cut_edges;
138+
for (size_t i = 0; i < n; i++) {
139+
cut_edges = min_cut(graph, i, (i + 1) % n);
140+
if (cut_edges.size() == 3) {
141+
break;
142+
}
143+
}
144+
assert(cut_edges.size() == 3);
145+
146+
vector<bool> visited(n, false);
147+
vector<size_t> groups_size;
148+
for (size_t i = 0; i < n; i++) {
149+
if (visited[i]) continue;
150+
groups_size.push_back(count_connected(graph, i, visited, cut_edges));
151+
}
152+
assert(groups_size.size() == 2);
153+
154+
cout << groups_size[0] * groups_size[1] << endl;
155+
156+
return 0;
157+
}

0 commit comments

Comments
 (0)