Resources:
wikipedia.org
ম্যাক্সিমাম ফ্লো (১)
ম্যাক্সিমাম ফ্লো (২)
Topcoder tutorial link
One problem solution discussion
CP Algorithms
Implementation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///http://lightoj.com/volume_showproblem.php?problem=1153 | |
#include <bits/stdc++.h> | |
using namespace std; | |
#define INF 1<<30 | |
#define endl '\n' | |
#define maxn 1000005 | |
#define FASTIO ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0); | |
typedef long long ll; | |
const double PI = acos(-1.0); | |
const ll mod = 1e9 + 7; | |
inline void normal(ll &a) { a %= mod; (a < 0) && (a += mod); } | |
inline ll modMul(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a * b) % mod; } | |
inline ll modAdd(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a + b) % mod; } | |
inline ll modSub(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); a -= b; normal(a); return a; } | |
inline ll modPow(ll b, ll p) { ll r = 1; while (p) { if (p & 1) r = modMul(r, b); b = modMul(b, b); p >>= 1; } return r; } | |
inline ll modInverse(ll a) { return modPow(a, mod - 2); } | |
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); } | |
/** | |
template < typename F, typename S > | |
ostream& operator << ( ostream& os, const pair< F, S > & p ) { | |
return os << "(" << p.first << ", " << p.second << ")"; | |
} | |
template < typename T > | |
ostream &operator << ( ostream & os, const vector< T > &v ) { | |
os << "{"; | |
for (auto it = v.begin(); it != v.end(); ++it) { | |
if ( it != v.begin() ) os << ", "; | |
os << *it; | |
} | |
return os << "}"; | |
} | |
template < typename T > | |
ostream &operator << ( ostream & os, const set< T > &v ) { | |
os << "["; | |
for (auto it = v.begin(); it != v.end(); ++it) { | |
if ( it != v.begin()) os << ", "; | |
os << *it; | |
} | |
return os << "]"; | |
} | |
template < typename F, typename S > | |
ostream &operator << ( ostream & os, const map< F, S > &v ) { | |
os << "["; | |
for (auto it = v.begin(); it != v.end(); ++it) { | |
if ( it != v.begin() ) os << ", "; | |
os << it -> first << " = " << it -> second ; | |
} | |
return os << "]"; | |
} | |
#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0) | |
clock_t tStart = clock(); | |
#define timeStamp dbg("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC) | |
void faltu () { cerr << endl; } | |
template <typename T> | |
void faltu( T a[], int n ) { | |
for (int i = 0; i < n; ++i) cerr << a[i] << ' '; | |
cerr << endl; | |
} | |
template <typename T, typename ... hello> | |
void faltu( T arg, const hello &... rest) { cerr << arg << ' '; faltu(rest...); } | |
// Program showing a policy-based data structure. | |
#include <ext/pb_ds/assoc_container.hpp> // Common file | |
#include <ext/pb_ds/tree_policy.hpp> | |
#include <functional> // for less | |
#include <iostream> | |
using namespace __gnu_pbds; | |
using namespace std; | |
// GNU link : https://goo.gl/WVDL6g | |
typedef tree<int, null_type, less_equal<int>, rb_tree_tag, | |
tree_order_statistics_node_update> | |
new_data_set; | |
// find_by_order(k) – ফাংশনটি kth ordered element এর একটা পয়েন্টার রিটার্ন করে। অর্থাৎ তুমি চাইলেই kth ইন্ডেক্সে কি আছে, সেটা জেনে ফেলতে পারছো! | |
// order_of_key(x) – ফাংশনটি x এলিমেন্টটা কোন পজিশনে আছে সেটা বলে দেয়। | |
//*//**___________________________________________________**/ | |
const int inf = 1e9; | |
const int N = 105; | |
struct Edge | |
{ | |
int to, rev; | |
int f, cap; | |
Edge(); | |
Edge(int to, int rev, int f, int cap): to(to), rev(rev), f(f), cap(cap) {} | |
}; | |
vector<Edge> graph[N]; | |
void addEdge(int u, int v, int cap) | |
{ | |
Edge a = Edge(v, (int)graph[v].size(), 0, cap); | |
Edge b = Edge(u, (int)graph[u].size(), 0, cap); | |
graph[u].push_back(a); | |
graph[v].push_back(b); | |
} | |
int n, start[N], level[N]; | |
queue<int> Q; | |
bool dinic_bfs(int s, int t) | |
{ | |
fill(level, level + n + 1, -1); | |
Q.push(s); | |
level[s] = 0; | |
while (!Q.empty()) { | |
int u = Q.front(); | |
Q.pop(); | |
for (int i = 0; i < (int)graph[u].size(); i++) { | |
Edge &E = graph[u][i]; | |
int v = E.to; | |
if (level[v] < 0 && E.f < E.cap) { | |
Q.push(v); | |
level[v] = level[u] + 1; | |
} | |
} | |
} | |
return level[t] >= 0; | |
} | |
int dinic_dfs(int u, int dst, int flow) | |
{ | |
if (u == dst) return flow; | |
for (int &i = start[u]; i < (int)graph[u].size(); i++) { | |
Edge &E = graph[u][i]; | |
int v = E.to; | |
if (level[v] == level[u] + 1 && E.f < E.cap) { | |
int cur_flow = dinic_dfs(v, dst, min(flow, E.cap - E.f)); | |
if (cur_flow > 0) { | |
E.f += cur_flow; | |
graph[v][E.rev].f -= flow; | |
return cur_flow; | |
} | |
} | |
} | |
return 0; | |
} | |
int dinic_flow(int s, int t) | |
{ | |
int flow = 0; | |
while ((dinic_bfs(s, t))) { | |
fill(start, start + n + 1, 0); | |
int delta; | |
while ((delta = dinic_dfs(s, t, INT_MAX))) flow += delta; | |
} | |
return flow; | |
} | |
int main() | |
{ | |
//FASTIO | |
///* | |
#ifndef ONLINE_JUDGE | |
freopen("in.txt", "r", stdin); | |
freopen("out.txt", "w", stdout); | |
freopen("error.txt", "w", stderr); | |
#endif | |
//*/ | |
int T; | |
scanf("%d", &T); | |
for (int cs = 1; cs <= T; cs++) { | |
scanf("%d", &n); | |
int s, t, c; | |
scanf("%d %d %d", &s, &t, &c); | |
while (c--) { | |
int u, v, w; | |
scanf("%d %d %d", &u, &v, &w); | |
addEdge(u, v, w); | |
} | |
int ans = dinic_flow(s, t); | |
printf("Case %d: %d\n", cs, ans); | |
for (int i = 0; i <= n; i++) | |
graph[i].clear(); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///http://lightoj.com/volume_showproblem.php?problem=1155 | |
#include <bits/stdc++.h> | |
using namespace std; | |
#define INF 1<<30 | |
#define endl '\n' | |
#define maxn 1000005 | |
#define FASTIO ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0); | |
typedef long long ll; | |
const double PI = acos(-1.0); | |
const ll mod = 1e9 + 7; | |
inline void normal(ll &a) { a %= mod; (a < 0) && (a += mod); } | |
inline ll modMul(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a * b) % mod; } | |
inline ll modAdd(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a + b) % mod; } | |
inline ll modSub(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); a -= b; normal(a); return a; } | |
inline ll modPow(ll b, ll p) { ll r = 1; while (p) { if (p & 1) r = modMul(r, b); b = modMul(b, b); p >>= 1; } return r; } | |
inline ll modInverse(ll a) { return modPow(a, mod - 2); } | |
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); } | |
/** | |
template < typename F, typename S > | |
ostream& operator << ( ostream& os, const pair< F, S > & p ) { | |
return os << "(" << p.first << ", " << p.second << ")"; | |
} | |
template < typename T > | |
ostream &operator << ( ostream & os, const vector< T > &v ) { | |
os << "{"; | |
for (auto it = v.begin(); it != v.end(); ++it) { | |
if ( it != v.begin() ) os << ", "; | |
os << *it; | |
} | |
return os << "}"; | |
} | |
template < typename T > | |
ostream &operator << ( ostream & os, const set< T > &v ) { | |
os << "["; | |
for (auto it = v.begin(); it != v.end(); ++it) { | |
if ( it != v.begin()) os << ", "; | |
os << *it; | |
} | |
return os << "]"; | |
} | |
template < typename F, typename S > | |
ostream &operator << ( ostream & os, const map< F, S > &v ) { | |
os << "["; | |
for (auto it = v.begin(); it != v.end(); ++it) { | |
if ( it != v.begin() ) os << ", "; | |
os << it -> first << " = " << it -> second ; | |
} | |
return os << "]"; | |
} | |
#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0) | |
clock_t tStart = clock(); | |
#define timeStamp dbg("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC) | |
void faltu () { cerr << endl; } | |
template <typename T> | |
void faltu( T a[], int n ) { | |
for (int i = 0; i < n; ++i) cerr << a[i] << ' '; | |
cerr << endl; | |
} | |
template <typename T, typename ... hello> | |
void faltu( T arg, const hello &... rest) { cerr << arg << ' '; faltu(rest...); } | |
// Program showing a policy-based data structure. | |
#include <ext/pb_ds/assoc_container.hpp> // Common file | |
#include <ext/pb_ds/tree_policy.hpp> | |
#include <functional> // for less | |
#include <iostream> | |
using namespace __gnu_pbds; | |
using namespace std; | |
// GNU link : https://goo.gl/WVDL6g | |
typedef tree<int, null_type, less_equal<int>, rb_tree_tag, | |
tree_order_statistics_node_update> | |
new_data_set; | |
// find_by_order(k) – ফাংশনটি kth ordered element এর একটা পয়েন্টার রিটার্ন করে। অর্থাৎ তুমি চাইলেই kth ইন্ডেক্সে কি আছে, সেটা জেনে ফেলতে পারছো! | |
// order_of_key(x) – ফাংশনটি x এলিমেন্টটা কোন পজিশনে আছে সেটা বলে দেয়। | |
//*//**___________________________________________________**/ | |
const int inf = 1e9; | |
const int N = 210; | |
struct Edge | |
{ | |
int to, rev; | |
int f, cap; | |
Edge(); | |
Edge(int to, int rev, int f, int cap): to(to), rev(rev), f(f), cap(cap) {} | |
}; | |
vector<Edge> graph[N]; | |
void addEdge(int u, int v, int cap) | |
{ | |
Edge a = Edge(v, (int)graph[v].size(), 0, cap); | |
Edge b = Edge(u, (int)graph[u].size(), 0, 0); // for directed grap capacity 0 | |
graph[u].push_back(a); | |
graph[v].push_back(b); | |
} | |
int nodes, start[N], level[N]; | |
queue<int> Q; | |
bool dinic_bfs(int s, int t) | |
{ | |
fill(level, level + nodes + 1, -1); | |
Q.push(s); | |
level[s] = 0; | |
while (!Q.empty()) { | |
int u = Q.front(); | |
Q.pop(); | |
for (int i = 0; i < (int)graph[u].size(); i++) { | |
Edge &E = graph[u][i]; | |
int v = E.to; | |
if (level[v] < 0 && E.f < E.cap) { | |
Q.push(v); | |
level[v] = level[u] + 1; | |
} | |
} | |
} | |
return level[t] >= 0; | |
} | |
int dinic_dfs(int u, int dst, int flow) | |
{ | |
if (u == dst) return flow; | |
for (int &i = start[u]; i < (int)graph[u].size(); i++) { | |
Edge &E = graph[u][i]; | |
int v = E.to; | |
if (level[v] == level[u] + 1 && E.f < E.cap) { | |
int cur_flow = dinic_dfs(v, dst, min(flow, E.cap - E.f)); | |
if (cur_flow > 0) { | |
E.f += cur_flow; | |
graph[v][E.rev].f -= cur_flow; | |
return cur_flow; | |
} | |
} | |
} | |
return 0; | |
} | |
int dinic_flow(int s, int t) | |
{ | |
//dbg(s, t); | |
int flow = 0; | |
while ((dinic_bfs(s, t))) { | |
fill(start, start + nodes + 1, 0); | |
int delta; | |
while ((delta = dinic_dfs(s, t, INT_MAX))) flow += delta; | |
} | |
return flow; | |
} | |
int main() | |
{ | |
//FASTIO | |
///* | |
#ifndef ONLINE_JUDGE | |
freopen("in.txt", "r", stdin); | |
freopen("out.txt", "w", stdout); | |
freopen("error.txt", "w", stderr); | |
#endif | |
//*/ | |
int T; | |
scanf("%d", &T); | |
for (int cs = 1; cs <= T; cs++) { | |
int n; | |
scanf("%d", &n); | |
for (int i = 1; i <= n; i++) { | |
int x; | |
scanf("%d", &x); | |
addEdge(i, i + n, x); | |
} | |
nodes = 2 * n + 2; | |
int s = 0, t = nodes - 1, c; | |
scanf("%d", &c); | |
while (c--) { | |
int u, v, w; | |
scanf("%d %d %d", &u, &v, &w); | |
addEdge(u + n, v, w); | |
} | |
int B, D; | |
scanf("%d %d", &B, &D); | |
while (B--) { | |
int x; | |
scanf("%d", &x); | |
addEdge(s, x, inf); | |
} | |
while (D--) { | |
int x; | |
scanf("%d", &x); | |
addEdge(x + n, t, inf); | |
} | |
int ans = dinic_flow(s, t); | |
printf("Case %d: %d\n", cs, ans); | |
for (int i = 0; i < nodes; i++) | |
graph[i].clear(); | |
} | |
return 0; | |
} |
No comments:
Post a Comment