알고리즘/백준
[백준] 2679번 - 맨체스터의 도로
래울
2024. 9. 17. 17:31
문제
https://www.acmicpc.net/problem/2679
Network Flow + DFS
'A에서 B로 가는 중복 비율은 A에서 B로 가는 모든 길을 동시에 이용했을 때 1시간 동안 B에 도착할 수 있는 차의 최대 개수와 길 1개를 이용했을 때 도착할 수 있는 최대 개수의 비율이다.'
A. A에서 B로 가는 모든 길을 동시에 이용하는 경우
B. 길 1개를 이용했을 때 도착할 수 있는 경우
A / B를 구하시오.
원문이 번역된 문제라, 뭔 소리인가 몇 번 읽어봤다.
A는 최대유량을 구하라는 의미이고, B는 최대유량으로 구해지는 source->sink의 경로 중 하나에 대한 최대유량을 의미한다.
B의 경우에는 최대유량, 다익스트라 돌려보다 결국 DFS로 다 돌렸다.
해당 길을 이루는 간선들 중 최소 용량을 가지고 가면서 DFS를 돌려주면 된다.
초기화 까먹고 이왜않하다가 계속 틀린듯
코드
#include<iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
int T;
//정점개수, 간선 수, A->B
int N, E, A, B;
int capacity[1001][1001];
int flow[1001][1001];
struct Node {
int n, c;
bool operator<(Node o) const {
return c < o.c;
}
};
vector<Node> graph[1001];
int networkFlow(int source, int sink)
{
int result = 0;
while (true)
{
int parent[1001];
memset(parent, -1, sizeof(parent));
queue<int> q;
q.push(source);
parent[source] = source;
while (!q.empty() && parent[sink] == -1) {
int now = q.front();
q.pop();
for (int i = 0; i < N; ++i) {
if (capacity[now][i] - flow[now][i] <= 0) continue;
if (parent[i] == -1) {
parent[i] = now;
q.push(i);
}
}
}
if (parent[sink] == -1) break;
int mv = 1987654321;
for (int i = sink; i != source; i = parent[i]) {
mv = min(mv, capacity[parent[i]][i] - flow[parent[i]][i]);
}
for (int i = sink; i != source; i = parent[i]) {
flow[parent[i]][i] += mv;
flow[i][parent[i]] -= mv;
}
result += mv;
}
return result;
}
int visited[1001];
int answer = 0;
void dfs(int nxt, int v) {
if (nxt == B) {
answer = max(v, answer);
return;
}
for (int i = 0; i < graph[nxt].size(); ++i) {
if (visited[graph[nxt][i].n]) continue;
visited[graph[nxt][i].n] = 1;
dfs(graph[nxt][i].n, min(v, graph[nxt][i].c));
visited[graph[nxt][i].n] = 0;
}
}
void solve() {
for (int i = 0; i < N; ++i) graph[i].clear();
answer = 0;
memset(visited, 0, sizeof(visited));
memset(capacity, 0, sizeof(capacity));
memset(flow, 0, sizeof(flow));
cin >> N >> E >> A >> B;
for (int i = 0; i < E; ++i) {
int a, b, c;
cin >> a >> b >> c;
capacity[a][b] = c;
graph[a].push_back({ b, c });
}
visited[A] = 1;
dfs(A, 1987654321);
cout << (float(networkFlow(A, B)) / answer) << " ";
}
int main(int argc, char** argv)
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cout.precision(3);
cout << fixed;
cin >> T;
for (int i = 0; i < T; ++i) {
solve();
}
return 0;
}