백준2311 왕복 여행 작성일 2019-10-02 | In PS 문제 링크 http://icpc.me/2311 사용 알고리즘 MCMF 풀이 간단한 MCMF 문제입니다. 정점 분할을 해주면 쉽게 구현할 수 있습니다. 전체 코드 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071#include <bits/stdc++.h> using namespace std; typedef long long ll; int c[2020][2020]; int d[2020][2020]; int f[2020][2020]; vector<int> g[2020]; inline int in(int x){ return x << 1; } inline int out(int x){ return x << 1 | 1; } void setVertex(int x){ c[in(x)][out(x)] = 1e9; g[in(x)].push_back(out(x)); c[out(x)][in(x)] = 1e9; g[out(x)].push_back(in(x)); } void addEdge(int s, int e, int x){ g[s].push_back(e); c[s][e] = 1; d[s][e] = x; g[e].push_back(s); d[e][s] = -x; } void addPath(int s, int e, int x){ addEdge(out(s), in(e), x); addEdge(out(e), in(s), x); } int n, m; ll flow(int s, int t){ ll ret = 0; int inq[2020]; memset(inq, 0, sizeof inq); int par[2020]; memset(par, -1, sizeof par); int dst[2020]; memset(dst, 0x3f, sizeof dst); queue<int> q; q.push(s); inq[s] = 1; dst[s] = 0; while(q.size()){ int now = q.front(); q.pop(); inq[now] = 0; for(auto nxt : g[now]){ if(c[now][nxt] - f[now][nxt] > 0 && dst[nxt] > dst[now] + d[now][nxt]){ par[nxt] = now; dst[nxt] = dst[now] + d[now][nxt]; if(!inq[nxt]){ q.push(nxt); inq[nxt] = 1; } } } } for(int i=t; i!=s; i=par[i]){ ret += d[par[i]][i]; f[par[i]][i]++; f[i][par[i]]--; } return ret; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> m; int s = out(1), t = in(n); for(int i=1; i<=n; i++) setVertex(i); for(int i=1; i<=m; i++){ int s, e, x; cin >> s >> e >> x; addPath(s, e, x); } ll ans = flow(s, t) + flow(s, t); cout << ans; }