Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- using namespace __gnu_pbds;
- using namespace std;
- #define int long long
- #define mp make_pair
- #define pb push_back
- #pragma GCC optimize("Ofast")
- #pragma GCC optimize("unroll-loops")
- constexpr int INF = (int)1e18;
- constexpr int N = (int)5e5 + 111;
- constexpr int md = (int)998244353;
- constexpr int mdPower = (int)1e9+7 - 1;
- mt19937 rnd(time(nullptr));
- void add(int& a,int b){
- a += b; if(a >= md) a -= md;
- }
- void sub(int& a,int b){
- a -= b; while(a < 0) a += md;
- }
- void add(__int128& a,int b){
- a += b;
- }
- void sub(__int128& a,int b){
- a -= b;
- }
- int bpow(int a,int b){
- if(b == 0)
- return 1;
- if(b % 2 == 0){
- int t = bpow(a,b>>1);
- return t*t%md;
- }
- return a*bpow(a,b-1) % md;
- }
- int inv(int a){
- return bpow(a,md-2);
- }
- int fac[N],invfac[N];
- void init(){
- fac[0] = 1;
- for(int i = 1; i < N; i++){
- fac[i] = (fac[i-1] * i) % md;
- }
- invfac[N-1] = inv(fac[N-1]);
- for(int i = N-2; i >= 0; i--){
- invfac[i] = (invfac[i+1] * (i+1))%md;
- }
- return;
- }
- int C(int n,int k){
- return fac[n] * invfac[k] % md * invfac[n-k] % md;
- }
- struct edge{
- int to,flow,cap,id;
- edge(){}
- edge(int to,int flow,int cap,int id):to(to),flow(flow),cap(cap),id(id){}
- };
- vector<edge> e;
- vector<int> g[N];
- void add_edge(int a,int b,int cap,int id){
- g[a].pb(e.size());
- e.pb(edge(b,0,cap,id));
- g[b].pb(e.size());
- e.pb(edge(a,0,0,0));
- // cout << a << " " << b << " " << cap << "\n";
- return;
- }
- bool used[N];
- int d[N];
- int ptr[N];
- int s,f;
- int n;
- bool bfs(){
- for(int i = 0; i <= n+n; i++)
- used[i] = false, d[i] = -1;
- d[s] = 0;
- used[s] = 1;
- queue<int> q;
- q.push(s);
- while(!q.empty()){
- int v = q.front();
- // cerr << "bfs v = " << v << "\n";
- q.pop();
- for(auto& i : g[v]){
- int& to = e[i].to, flow = e[i].flow, cap = e[i].cap;
- if(flow < cap && d[to] == -1){
- d[to] = d[v] + 1;
- q.push(to);
- }
- }
- }
- return d[f] != -1;
- }
- int dfs(int v,int flow = INF){
- if(flow <= 0)
- return 0;
- if(v == f)
- return flow;
- // cerr << "v = " << v << "\n";
- for(; ptr[v] < g[v].size(); ptr[v]++){
- int i = g[v][ptr[v]];
- int& to = e[i].to;
- int& F = e[i].flow;
- int& cap = e[i].cap;
- // cerr << "to = " << to << "\n";
- // cerr << d[v] << " " << d[to] << "\n";
- // cerr << "cap = " << cap << ", flow = " << F << "\n";
- if(d[to] != d[v] + 1)
- continue;
- int fl = min(flow,cap - F);
- // cerr << "fl = " << fl << "\n";
- int pushed = dfs(to,fl);
- if(pushed){
- e[i].flow += pushed;
- e[i^1].flow -= pushed;
- return pushed;
- }
- }
- return 0;
- }
- int dinic(){
- int flow = 0;
- while(true){
- if(!bfs()) break;
- memset(ptr,0,sizeof ptr);
- while(int pushed = dfs(s))
- flow += pushed;
- }
- return flow;
- }
- set<int> ans;
- void dfs1(int v){
- // used[v] = 1;
- d[v] = 1;
- for(auto& i : g[v]){
- int& to = e[i].to;
- int& id = e[i].id;
- if(d[to] == 0 && e[i].cap > e[i].flow){
- dfs1(to);
- }
- }
- return;
- }
- void dfs2(int v){
- used[v] = 1;
- for(auto& i : g[v]){
- int& to = e[i].to;
- int& flow = e[i].flow;
- int& cap = e[i].cap;
- int& id = e[i].id;
- if(d[to] == 0 && cap == flow && cap > 0){
- cerr << "adding " << v << " " << to << "\n";
- ans.insert(id);
- }
- }
- for(auto& i : g[v]){
- int& to = e[i].to;
- int& id = e[i].id;
- if(!used[to] && e[i].cap > e[i].flow){
- dfs2(to);
- }
- }
- return;
- }
- void solve(){
- int m;
- cin >> n >> m;
- cin >> s >> f;
- for(int i = 1; i <= n; i++){
- int x;
- cin >> x;
- add_edge(i,i+n,x,i);
- }
- for(int i = 0; i < m; i++){
- int a,b;
- cin >> a >> b;
- add_edge(a+n,b,INF,0);
- add_edge(b+n,a,INF,0);
- }
- int flow = dinic();
- cerr << "MAXFLOW = " << flow << "\n";
- bfs();
- memset(d,0,sizeof d);
- memset(used,0,sizeof used);
- dfs1(s);
- dfs2(s);
- ans.erase(0);
- for(auto& x : ans)
- cout << x << " ";
- return;
- }
- signed main(){
- ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
- int tests = 1;
- // cin >> tests;
- for(int test = 1; test <= tests; test++){
- solve();
- }
- return 0;
- }
- /**
- Jee, you see?
- sum <= r
- z & (1 << bt) == 1
- 1.
- dp[sum] += dp[sum-(1<<bt)]
- 2. (N-(r>>bt)&1)
- dp[sum] += dp[sum-(1<<bt)*2]
- **/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement