Dinic algorithm implementation and a spoj puzzle - algorithm

I am trying to solve this problem on http://www.spoj.com/problems/FASTFLOW/
I suppose dinic's algorithm is suitable for this problem. But it runs in O(E.V^2) time which is too slow for this problem in the worst case. Any suggestions for a different algorithm or for improving the running time of this algorithm?
EDIT: I am including my implementation of dinic's algorithm. Apparently, it contains some mistake...Could anyone give some test case or help in debugging the logic of program.
//#define DEBUG //comment when you have to disable all debug macros.
#define NDEBUG //comment when all assert statements have to be disabled.
#include <iostream>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <climits>
#include <ctime>
#include <algorithm>
#include <functional>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <sys/time.h>
#include <iomanip>
#include <cstdarg>
#include <utility> //std::pair
#include <cassert>
#define tr(c,i) for(typeof(c.begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define log2(x) (log(x)/log(2))
#define ARRAY_SIZE(arr) (1[&arr]-arr)
#define INDEX(arr,elem) (lower_bound(all(arr),elem)-arr.begin())
#define lld long long int
#define MOD 1000000007
#define gcd __gcd
#define equals(a,b) (a.compareTo(b)==0) //for strings only
using namespace std;
#ifdef DEBUG
#define debug(args...) {dbg,args; cerr<<endl;}
#else
#define debug(args...) // Just strip off all debug tokens
#endif
struct debugger
{
template<typename T> debugger& operator , (const T& v)
{
cerr<<v<<" ";
return *this;
}
}dbg;
/**********************************MAIN CODE***************************************************/
//runs in O(V^2E) time.
//might consider using a 1-d array of size V*V for large values of V
vector<vector<lld> > flow, capacity, level_graph;
lld V;
vector<lld> *adj, *level_adj;
void init(lld v)
{
adj=new vector<lld>[v+1];
level_adj=new vector<lld>[v+1];
V=v;
flow.resize(V+1);
capacity.resize(V+1);
level_graph.resize(V+1);
for(lld i=0;i<=V;i++)
flow[i].resize(V+1), capacity[i].resize(V+1), level_graph[i].resize(V+1);
}
void add_edge(lld u, lld v, lld uv, lld vu=0)
{
capacity[u][v]=uv;
capacity[v][u]=vu;
adj[u].push_back(v);
flow[u][v]=uv; //will store the present capacity. facility for the residual graph
flow[v][u]=vu;
if(vu) adj[v].push_back(u);
}
void update_residual_graph(lld source, lld destination, lld *parent) //push augment flow in the residual graph and modify the latter.
{
lld i=destination, aug=LLONG_MAX;
while(parent[i]!=-2)
{
//debug(i);
aug=min(aug,flow[parent[i]][i]);
i=parent[i];
}
i=destination;
while(parent[i]!=-2)
{
flow[parent[i]][i]-=aug;
flow[i][parent[i]]=capacity[parent[i]][i]-flow[parent[i]][i];
i=parent[i];
}
}
bool DFS(lld source, lld destination)
{
stack<lld> state;
bool visited[V+1], present;
lld parent[V+1],t;
memset(visited, false, sizeof(visited));
memset(parent, -1, sizeof(parent));
parent[source]=-2;
state.push(source);
visited[source]=true;
while(!state.empty())
{
t=state.top();
present=false;
for(vector<lld>::iterator it=level_adj[t].begin(); it!=level_adj[t].end();it++)
{
parent[*it]=t;
if(!visited[*it] && level_graph[t][*it])
{
present=true;
state.push(*it);
visited[*it]=true;
if(*it==destination)
update_residual_graph(source,destination,parent); //update residual graph
}
}
if(!present)
state.pop();
}
return parent[destination]!=-1;
}
bool BFS(lld source, lld destination)
{
//create level graph usign BFS
fill(level_graph.begin(), level_graph.end(), vector<lld>(V+1,-1));
lld i,j;
for(i=1;i<=V;i++)
level_adj[i].clear();
queue<lld> state;
lld level[V+1],t; //record of minimum distance from source
memset(level,-1, sizeof(level));
state.push(source);
level[source]=0;
while(!state.empty())
{
t=state.front();
state.pop();
for(vector<lld>::iterator it=adj[t].begin();it!=adj[t].end();it++)
{
if((level[*it]==-1 && flow[t][*it]) || (level[*it]==level[t]+1))
{
level_graph[t][*it]=flow[t][*it];
level_adj[t].push_back(*it);
level[*it]=level[t]+1;
state.push(*it);
}
}
}
if(level[destination]==-1)
return false;
//call DFS and update the residual graph
return DFS(source,destination);
}
lld maximum_flow(lld source, lld destination)
{
while(BFS(source,destination));
lld max_flow=0;
for(vector<lld>::iterator it=adj[source].begin(); it!=adj[source].end(); it++)
max_flow+=flow[*it][source];
return max_flow;
}
int main()
{
lld e,u,v,n,c;
//cout<<"V:"<<endl;
cin>>n>>e;
init(n);
while(e--)cin>>u>>v>>c, add_edge(u,v,c);
cout<<maximum_flow(1,n)<<endl;
}

The push-relabel algorithm with the global relabeling heuristic proposed by Cherkassky--Goldberg should be sufficient (every m steps, recompute the labels with breadth-first search). The practical running times with the heuristic are much, much better than the worst-case cubic bound. (You could do gap relabeling too, but it's trickier to implement and probably not necessary for this application.)

Related

How to copy characters into string vector

Attempting to copy from a character vector to a string vector has been unsuccessful across multiple attempts at a solution
allocating memory to the vector prior to copying allows std::copy to work properly when placed at "OutputIterator result" (based on function template). I attempted:
std::copy(char1.begin(), char1.end(), v1.begin());
however, this was unsuccessful as well. using back_inserter returns error c2679 "binary '=': no operator found which takes a right-hand operand of type'char' (or there is no acceptable conversion).
input file is located here: https://adventofcode.com/2018/day/2
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iterator>
#include <cstdio>
int main() {
std::string field1;
std::string field2;
char characters;
std::vector<char>::iterator ptr;
std::vector<char>::iterator ptr2;
std::vector<char> char1;
std::vector<char> char2;
int size = 0;
std::ifstream inFile;
inFile.open("C:\\Users\\Administrator\\Desktop\\c++ files\\input2.txt");
if (!inFile) {
std::cout << "abort";
return 1;
}
while (inFile >> characters) { //read variables from input stream
char1.push_back(characters);
}
std::vector<std::string> v1(6500);
std::copy(char1.begin(), char1.end(), std::back_inserter(v1));
inFile.close();
return 0;
}
//26
expect vector v1 to hold values in vector char1. I am assuming the problem stems from the data type of v1 vs. char1, however, I have not been able to find a concrete solution. I do not want to read directly into a string vector; hence my current problem.
I am not sure what you try to achieve. Here few examples:
#include <string>
#include <vector>
int main()
{
std::string str1{ "Just for an example" }; // You can read it from a file
std::vector<std::string> vct_str1(32); // Lets say it has 32 std::string items
std::vector<std::string> vct_str2(32); // Lets say it has 32 std::string items
// **** A. Copy from std::string to std::vector<char>: ****
std::vector<char> vct_ch(str1.begin(), str1.end()); // On construction
// Or later: vct_ch.assign(str1.begin(), str1.end());
// **** B. Copy from std::vector<char> to std::string: ****
std::string str2(vct_ch.begin(), vct_ch.end()); // On construction
// Or later: str2.assign(vct_ch.begin(), vct_ch.end());
// **** C. Copy from std::vector<char> to std::vector<std::string>: ****
vct_str1[0].assign(vct_ch.begin(), vct_ch.end()); // Which is similar to B
// **** D. Source & Dest Types same as in Case-C But char per std::string: ****
int i = 0;
vct_str2.resize(vct_ch.size());
for (auto item : vct_ch)
vct_str2[i++] = item;
return 0;
}

Boost::spirit::qi - How do I build a parse rule that sets a property?

I'd like to build a rule that takes in a few parameters from a parsed line then sets a few as constant. Is that possible? An (invalid) example to illustrate what I'm trying to do is below. I think I'm using _r1 incorrectly here, but I'm not sure how to get at the right thing. Assume I don't want to just modify r before sending it into the parser.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_plus.hpp>
#include <boost/spirit/include/qi_sequence.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/phoenix/bind/bind_function.hpp>
#include <string>
using namespace boost::spirit::qi;
struct Sample
{
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
const rule<std::string::const_iterator, Sample()> AnythingAndOne = int_ >> eps[_r1.b = 1] >> eoi;
int main()
{
std::string z("3");
Sample r;
parse(z.begin(), z.end(), AnythingAndOne, r);
return 0;
}
Again, with reference to Boost Spirit: "Semantic actions are evil"? I'd avoid the semantic action.
You can directly synthesize a particular attribute value by using qi::attr:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
struct Sample {
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
namespace qi = boost::spirit::qi;
int main()
{
std::string const z("3");
Sample r;
qi::rule<std::string::const_iterator, Sample()> AnythingAndOne
= qi::int_ >> qi::attr(1) >> qi::eoi;
if (parse(z.begin(), z.end(), AnythingAndOne, r))
std::cout << "Parsed: " << boost::fusion::as_vector(r) << "\n";
else
std::cout << "Parse failed\n";
}
Prints
Parsed: (3 1)

how to find the minimum number of ascending subsequence

I meet a problem. http://poj.org/problem?id=1065
The problem is to find the minimum number of ascending subsequences.
I see somebody is to find the length of longest descending subsequences.
I don't know why the two numbers are equal.
#include <iostream>
#include <algorithm>
#include <functional>
#include <memory.h>
/* run this program using the console pauser or add your own getch,
system("pause") or input loop */
using namespace std;
pair<int,int> stick[5000];
int dp[5000];
int main(int argc, char** argv) {
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>stick[i].first>>stick[i].second;
}
sort(stick,stick+n);
memset(dp,-1,sizeof(int)*5000);
for(int i=0;i<n;i++){
*lower_bound(dp,dp+n,stick[i].second,greater<int>())=stick[i].second;
}
cout<<lower_bound(dp, dp + n, -1, greater<int>()) - dp<<endl;
}
return 0;
}
It follows immediately from the Dilworth's theorem. It's a standard technique for solving problems like this.

Why is C++ so much faster than C in this code?

My C code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char* a = (char*)malloc(200000);
for (int i = 0;i< 100000;i++){
strcat(a,"b");
}
printf("%s",a);
}
My C++ code is
#include <iostream>
int main(void){
std::string a = "";
for (int i = 0;i< 100000;i++){
¦ a+="b";
}
std::cout<<a;
}
On my machine, the C code runs in about 5 seconds, while on my machine, the C++ code runs in 0.025! seconds.
Now, the C code doesn't check for overflows, has no C++ overhead, classes and yet is quite a few magnitudes slower than my C++ code.
Using gcc/g++ 6.2.0 compiled with -O3 on Raspberry Pi.
#erwin was correct.
When I change my code to
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mystrcat(char* src,char* dest,int lenSrc){
src[lenSrc]=dest[0];
}
int main(void){
char* a = (char*)malloc(200000);
for (int i = 0;i< 100000;i++){
mystrcat(a,"b",i);
}
a[100000] = 0;
printf("%s\n",a);
}
It takes about .012s to run (mostly printing the large screen).
Shlemiel's the painter's algorithm at work!

Using a algorithm for searching a string in a vector

Is it possible to count how many strings are equal to one given as a parameter using an algorithm method?
#include <algorithm>
#include <vector>
#include <string>
int main(){
vector<string> vectorPeople;
//assume that myVector isn't empty
string name;
cin >> name;
int total=std::count(myVector.begin(),myVector.end(),name);
}
Yes. You can use std::count (you could've found that easily by a simple search).
#include <vector>
#include <algorithm>
#include <string>
int count(std::vector<std::string> strings , std::string to_search){
return std::count(strings.begin() , strings.end() , to_search);
}

Resources