Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // __________________
- // | ________________ |
- // || ____ ||
- // || /\ | ||
- // || /__\ | ||
- // || / \ |____ ||
- // ||________________||
- // |__________________|
- // \###################\
- // \###################\
- // \ ____ \
- // \_______\___\_______\
- // An AC a day keeps the doctor away.
- #pragma g++ optimize("Ofast")
- #pragma loop_opt(on)
- #include <bits/extc++.h>
- #ifdef local
- #define debug(x) (cerr<<#x<<" = "<<(x)<<'\n')
- #else
- #include <bits/stdc++.h>
- #define debug(x) ((void)0)
- #endif // local
- #define all(v) begin(v),end(v)
- #define siz(v) (ll(v.size()))
- #define get_pos(v,x) (lower_bound(all(v),x)-begin(v))
- #define sort_uni(v) sort(begin(v),end(v)),v.erase(unique(begin(v),end(v)),end(v))
- #define pb emplace_back
- #define ff first
- #define ss second
- #define mem(v,x) memset((v),(x),sizeof(v))
- using namespace std;
- using namespace __gnu_pbds;
- typedef int64_t ll;
- typedef long double ld;
- typedef pair<ll,ll> pll;
- typedef pair<ld,ld> pld;
- template <typename T> using max_heap = std::priority_queue<T,vector<T>,less<T> >;
- template <typename T> using min_heap = std::priority_queue<T,vector<T>,greater<T> >;
- template <typename T> using rbt = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
- constexpr ld PI = acos(-1), eps = 1e-7;
- constexpr ll N = 120025, INF = 1e18, MOD = 998244353, K = 20, inf = 1e9;
- constexpr inline ll cdiv(ll x, ll m) { return x/m + ((x<0 ^ m>0) && (x%m)); } // ceiling divide
- constexpr inline ll modpow(ll e,ll p,ll m=MOD) {ll r=1; for(e%=m;p;p>>=1,e=e*e%m) if(p&1) r=r*e%m; return r;}
- struct Dinic {
- struct Edge {
- int rest, to;
- } E[N];
- vector<int> G[N];
- int n, tot, dis[N], cur[N];
- void init(int _n) {
- n = _n;
- for(int i = 0; i < n; i++) G[i].clear();
- tot = 0;
- }
- void addEdge(int a, int b, int cap) {
- E[tot] = {cap, b}, G[a].pb(tot++);
- E[tot] = {0, a}, G[b].pb(tot++);
- }
- bool BFS(int s, int t) {
- for(int i = 0; i < n; i++) dis[i] = -1;
- queue<int> q;
- dis[s] = 0;
- q.push(s);
- while(!q.empty()) {
- int i = q.front(); q.pop();
- for(int id: G[i]) if(E[id].rest && dis[E[id].to] == -1) {
- dis[E[id].to] = dis[i] + 1;
- q.push(E[id].to);
- }
- }
- return dis[t] != -1;
- }
- int DFS(int i, int t, int lim) {
- if(i == t) return lim;
- int ans = 0;
- while(cur[i] < G[i].size() && lim) {
- int id = G[i][cur[i]++];
- if(dis[E[id].to] != dis[i]+1) continue;
- int f = DFS(E[id].to, t, min(lim, E[id].rest));
- E[id].rest -= f;
- E[id^1].rest += f;
- ans += f;
- lim -= f;
- }
- return ans;
- }
- int maxFlow(int s, int t) {
- int ans = 0;
- while(BFS(s,t)) {
- for(int i = 0; i < n; i++) cur[i] = 0;
- while(int f = DFS(s,t,inf)) ans += f;
- }
- return ans;
- }
- } flow;
- signed main() {
- ios_base::sync_with_stdio(0), cin.tie(0);
- int n, m;
- cin >> n >> m;
- flow.init(n+2);
- int sum = 0;
- for(int i = 1, v; i <= n; i++) {
- cin >> v;
- if(v >= 0)
- flow.addEdge(0, i, v), sum += v;
- else
- flow.addEdge(i, n+1, -v);
- }
- while(m--) {
- int a, b;
- cin >> a >> b;
- flow.addEdge(b, a, inf);
- }
- cout << sum - flow.maxFlow(0, n+1) << '\n';
- }
Advertisement
Add Comment
Please, Sign In to add comment