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
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;
}
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)
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.
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!
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);
}