Skip to content

adding Push Relabel Alg #1016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions DP/Inverse Coloring/1027e.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// http://codeforces.com/problemset/problem/1027/E
// E. Inverse Coloring

//$ time g++ -c -std=c++11 vec.cpp -fconstexpr-depth=600
//7keyet el STACK hethi work only on windows based sys. like CF; no need to change stack size on ACM/Kattis judge
//#pragma comment(linker, "/STACK:36777216")
//OPT COMPILER:global compiler c++11
//Lex MOD-0 ver. 2.4 (06/08/2018)
//la ilaha illallah
//{
#include<bits/stdc++.h>
#define ll long long
#define rep(i,n) for(auto i=0;i<(n);++i)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sz(v) v.size()
#define all(v) std::begin(v), std::end(v)
#define vi vector<int>
#define mod 1000000007LL

#define StringToInt(s,n) if ( ! (istringstream(s) >> n) ) n = 0;
using namespace std;
template <typename T>
string NumberToString ( T Number )
{
std::ostringstream ss;
ss << Number;
return ss.str();
}

#ifdef ONLINE_JUDGE
#define line
#define o(x)
#else
#define line cerr<<'\n';
#define o(x) cerr << __LINE__ << " $" << #x << " = " << x << "\n";
#endif // ONLINE_JUDGE

ll qpow(ll p,ll q)
{
ll f=1;
while(q) {
if(q&1)
f=f*p%mod;
p=p*p%mod;
q>>=1;
}
return f;
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') {
if (ch=='-')
f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
//}


const ll mod7=998244353LL;
inline ll add(ll _x, ll _y, ll _mod=mod7)
{
_x+=_y;
return _x>=_mod ? _x-_mod : _x;
}
inline ll sub(ll _x, ll _y, ll _mod=mod7)
{
_x-=_y;
return _x<0 ? _x+_mod : _x;
}
inline ll mul(ll _x, ll _y,ll _mod=mod7)
{
_x*=_y;
return _x>=_mod ? _x%_mod : _x;
}



int const N = 553;
ll t[N][N], cum[N][N];
#define after (in-ik-before)
int main()
{
#ifndef ONLINE_JUDGE
//freopen("a.txt", "r", stdin);
#endif // ONLINE_JUDGE
//preprocessing
rep(ik,501) cum[0][ik] = 1LL;
for(int in=1; in<=500; ++in) {
for(int ik=1; ik<=in; ++ik) {
for(int before=0; after>=0; ++before) {
t[in][ik] = add( t[in][ik], mul(cum[before][min(before,ik-1)], cum[after][min(after,ik)] ));
}
cum[in][ik] = add(cum[in][ik-1], t[in][ik] );
}
}

int n,k;
cin>>n>>k;
ll sol = 0LL;

for(int a=1; a<min(k,n+1); ++a) {
if (k%a==0)
sol = add( sol, mul(t [n][a], cum[n][min(n,(k-1)/a)] ));
else
sol = add( sol, mul(t [n][a], cum[n][min(n,k/a)] ));
}


//on ne peut pas factoriser le calcul des mat transpos�es
cout<<mul(sol,2LL);// x2, "Inverse Coloring" ^^
return 0;
}
250 changes: 250 additions & 0 deletions Graph/MinCost-MaxFlow/push-relabel alg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
// C++ program to implement push-relabel algorithm for
// getting maximum flow of graph
#include <bits/stdc++.h>
using namespace std;

struct Edge
{
// To store current flow and capacity of edge
int flow, capacity;

// An edge u--->v has start vertex as u and end
// vertex as v.
int u, v;

Edge(int flow, int capacity, int u, int v)
{
this->flow = flow;
this->capacity = capacity;
this->u = u;
this->v = v;
}
};

// Represent a Vertex
struct Vertex
{
int h, e_flow;

Vertex(int h, int e_flow)
{
this->h = h;
this->e_flow = e_flow;
}
};

// To represent a flow network
class Graph
{
int V; // No. of vertices
vector<Vertex> ver;
vector<Edge> edge;

// Function to push excess flow from u
bool push(int u);

// Function to relabel a vertex u
void relabel(int u);

// This function is called to initialize
// preflow
void preflow(int s);

// Function to reverse edge
void updateReverseEdgeFlow(int i, int flow);

public:
Graph(int V); // Constructor

// function to add an edge to graph
void addEdge(int u, int v, int w);

// returns maximum flow from s to t
int getMaxFlow(int s, int t);
};

Graph::Graph(int V)
{
this->V = V;

// all vertices are initialized with 0 height
// and 0 excess flow
for (int i = 0; i < V; i++)
ver.push_back(Vertex(0, 0));
}

void Graph::addEdge(int u, int v, int capacity)
{
// flow is initialized with 0 for all edge
edge.push_back(Edge(0, capacity, u, v));
}

void Graph::preflow(int s)
{
// Making h of source Vertex equal to no. of vertices
// Height of other vertices is 0.
ver[s].h = ver.size();

//
for (int i = 0; i < edge.size(); i++)
{
// If current edge goes from source
if (edge[i].u == s)
{
// Flow is equal to capacity
edge[i].flow = edge[i].capacity;

// Initialize excess flow for adjacent v
ver[edge[i].v].e_flow += edge[i].flow;

// Add an edge from v to s in residual graph with
// capacity equal to 0
edge.push_back(Edge(-edge[i].flow, 0, edge[i].v, s));
}
}
}

// returns index of overflowing Vertex
int overFlowVertex(vector<Vertex>& ver)
{
for (int i = 1; i < ver.size() - 1; i++)
if (ver[i].e_flow > 0)
return i;

// -1 if no overflowing Vertex
return -1;
}

// Update reverse flow for flow added on ith Edge
void Graph::updateReverseEdgeFlow(int i, int flow)
{
int u = edge[i].v, v = edge[i].u;

for (int j = 0; j < edge.size(); j++)
{
if (edge[j].v == v && edge[j].u == u)
{
edge[j].flow -= flow;
return;
}
}

// adding reverse Edge in residual graph
Edge e = Edge(0, flow, u, v);
edge.push_back(e);
}

// To push flow from overflowing vertex u
bool Graph::push(int u)
{
// Traverse through all edges to find an adjacent (of u)
// to which flow can be pushed
for (int i = 0; i < edge.size(); i++)
{
// Checks u of current edge is same as given
// overflowing vertex
if (edge[i].u == u)
{
// if flow is equal to capacity then no push
// is possible
if (edge[i].flow == edge[i].capacity)
continue;

// Push is only possible if height of adjacent
// is smaller than height of overflowing vertex
if (ver[u].h > ver[edge[i].v].h)
{
// Flow to be pushed is equal to minimum of
// remaining flow on edge and excess flow.
int flow = min(edge[i].capacity - edge[i].flow,
ver[u].e_flow);

// Reduce excess flow for overflowing vertex
ver[u].e_flow -= flow;

// Increase excess flow for adjacent
ver[edge[i].v].e_flow += flow;

// Add residual flow (With capacity 0 and negative
// flow)
edge[i].flow += flow;

updateReverseEdgeFlow(i, flow);

return true;
}
}
}
return false;
}

// function to relabel vertex u
void Graph::relabel(int u)
{
// Initialize minimum height of an adjacent
int mh = INT_MAX;

// Find the adjacent with minimum height
for (int i = 0; i < edge.size(); i++)
{
if (edge[i].u == u)
{
// if flow is equal to capacity then no
// relabeling
if (edge[i].flow == edge[i].capacity)
continue;

// Update minimum height
if (ver[edge[i].v].h < mh)
{
mh = ver[edge[i].v].h;

// updating height of u
ver[u].h = mh + 1;
}
}
}
}

// main function for printing maximum flow of graph
int Graph::getMaxFlow(int s, int t)
{
preflow(s);

// loop untill none of the Vertex is in overflow
while (overFlowVertex(ver) != -1)
{
int u = overFlowVertex(ver);
if (!push(u))
relabel(u);
}

// ver.back() returns last Vertex, whose
// e_flow will be final maximum flow
return ver.back().e_flow;
}

// Driver program to test above functions
int main()
{
int V = 6;
Graph g(V);

// Creating above shown flow network
g.addEdge(0, 1, 16);
g.addEdge(0, 2, 13);
g.addEdge(1, 2, 10);
g.addEdge(2, 1, 4);
g.addEdge(1, 3, 12);
g.addEdge(2, 4, 14);
g.addEdge(3, 2, 9);
g.addEdge(3, 5, 20);
g.addEdge(4, 3, 7);
g.addEdge(4, 5, 4);

// Initialize source and sink
int s = 0, t = 5;

cout << "Maximum flow is " << g.getMaxFlow(s, t);
return 0;
}