diff --git a/DP/Inverse Coloring/1027e.cpp b/DP/Inverse Coloring/1027e.cpp new file mode 100644 index 00000000..c798ebc8 --- /dev/null +++ b/DP/Inverse Coloring/1027e.cpp @@ -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 +#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 +#define mod 1000000007LL + +#define StringToInt(s,n) if ( ! (istringstream(s) >> n) ) n = 0; +using namespace std; +template +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 +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 ver; + vector 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& 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; +}