最大流,最大权二分匹配,二分匹配算法模板

其中Push Relabel不敢保证完全正确 因为PKU1273没有通过...

当然其它的也不能保证完全正确

 

ContractedBlock.gif ExpandedBlockStart.gif Ford Fulkerson
 
     
// PKU 1149
#include < vector >
#include
< queue >
using namespace std;

vector
< vector < int >> rec;
int pighouses[ 1001 ];
int M, N;

int nnodes;
int source, sink;
int ** cap;
int ** flow;
int parent[ 110 ];
int Mins[ 110 ];

int ford_fulkerson()
{
int cur,i;
queue
< int > Q;
int res = 0 ;
while ( true )
{
memset(parent,
0 , sizeof (parent));
memset(Mins,
0 , sizeof (Mins));
Mins[source]
= INT_MAX;
Q.push(source);
while ( ! Q.empty())
{
cur
= Q.front();
Q.pop();
for (i = 0 ;i < nnodes; ++ i)
{
if (Mins[i] == 0 && cap[cur][i] > flow[cur][i])
{
parent[i]
= cur;
Q.push(i);
Mins[i]
= min(cap[cur][i] - flow[cur][i],Mins[cur]);
}
}
}
if (Mins[sink] == 0 ) break ;
else
{
cur
= sink;
while (cur != source)
{
flow[parent[cur]][cur]
+= Mins[sink];
flow[cur][parent[cur]]
-= Mins[sink];
cur
= parent[cur];
}
res
+= Mins[sink];
}
}
return res;
}

 

 

ContractedBlock.gif ExpandedBlockStart.gif Hungarian_Algorithm
 
     
// PKU 1274
int N; // numbers of cows
int M; // numbers of stalls
char table[ 201 ][ 201 ];
int matcher[ 201 ];
char visit[ 201 ];

bool find( int idx)
{
int temp;
for ( int i = 1 ; i <= M; ++ i)
{
if (visit[i] == 0 && table[idx][i] > 0 )
{
visit[i]
= 1 ;
temp
= matcher[i];
matcher[i]
= idx;
if (temp == 0 || find(temp))
{
return true ;
}
matcher[i]
= temp;
}
}
return false ;
}

int bimatch()
{
int res = 0 ;
for ( int i = 1 ;i <= N; ++ i)
{
memset(visit,
0 , sizeof (visit));
if (find(i)) ++ res;
}
return res;
}

 

ContractedBlock.gif ExpandedBlockStart.gif Kuhn_Munkras
 
     
// Ural 1076
#include < iostream >
using namespace std;

int weight[ 151 ][ 151 ];
int visx[ 151 ];
int visy[ 151 ];
int lx[ 151 ];
int ly[ 151 ];
int linky[ 151 ];
int N;
int slack;

bool find( int idx)
{
int i,t;
visx[idx]
= 1 ;
for (i = 1 ;i <= N; ++ i)
{
if (visy[i]) continue ;
t
= lx[idx] + ly[i] - weight[idx][i];
if (t == 0 )
{
visy[i]
= 1 ;
if (linky[i] ==- 1 || find(linky[i]))
{
linky[i]
= idx;
return true ;
}
}
else
{
if (t < slack) slack = t;
}
}
return false ;
}

void KM()
{
int i,j;
for (i = 1 ;i <= N; ++ i) linky[i] = - 1 ;
for (i = 1 ;i <= N; ++ i)
{
lx[i]
= - 1 ;
for (j = 1 ;j <= N; ++ j)
{
if (lx[i] < weight[i][j]) lx[i] = weight[i][j];
}
}
for (i = 1 ;i <= N; ++ i)
{
while ( true )
{
for (j = 1 ;j <= N; ++ j){visx[j] = 0 ;visy[j] = 0 ;}
slack
= INT_MAX;
if (find(i)) break ;
for (j = 1 ;j <= N; ++ j)
{
if (visx[j]) lx[j] -= slack;
if (visy[j]) ly[j] += slack;
}
}
}
}

int main()
{
#ifndef ONLINE_JUDGE
freopen(
" input.txt " , " rt " , stdin);
freopen(
" output.txt " , " wt " , stdout);
#endif
int i,j;
int Sum, temp;
int Sum2;
cin
>> N;
Sum
= 0 ;
for (i = 1 ;i <= N; ++ i)
{
for (j = 1 ;j <= N; ++ j)
{
cin
>> temp;
Sum
+= temp;
weight[i][j]
= temp;
}
}
KM();
Sum2
= 0 ;
for (i = 1 ;i <= N; ++ i)
{
Sum2
+= weight[linky[i]][i];
}
cout
<< (Sum - Sum2);
return 0 ;
}

 

ContractedBlock.gif ExpandedBlockStart.gif Push_Relabel
 
     
// PKU 1149
#include < vector >
#include
< queue >
using namespace std;

vector
< vector < int >> rec;
int pighouses[ 1001 ];
int M, N;

int nnodes;
int source, sink;
int ** cap;
int ** flow;
int e[ 102 ];
int h[ 102 ];

void initialize_preflow()
{
memset(e,
0 , sizeof (e));
memset(h,
0 , sizeof (h));
h[source]
= nnodes;
for ( int i = 0 ; i < nnodes; ++ i)
{
if (cap[source][i] > 0 )
{
flow[source][i]
= cap[source][i];
flow[i][source]
= - cap[source][i];
e[i]
= cap[source][i];
e[source]
-= cap[source][i];
}
}

}

void push( int from, int to)
{
int Min = min(e[from],cap[from][to] - flow[from][to]);
e[from]
-= Min;
e[to]
+= Min;
flow[from][to]
+= Min;
flow[to][from]
-= Min;
}

void push_relabel()
{
static char label[ 102 ];
int i,cur,Min;
queue
< int > Q;
initialize_preflow();
memset(label,
0 , sizeof (label));
for (i = 0 ;i < nnodes; ++ i)
{
if (cap[source][i] > 0 && i != sink){
Q.push(i);
label[i]
= 1 ;
}
}
while ( ! Q.empty())
{
cur
= Q.front();
Min
= - 1 ;
for (i = 0 ;i < nnodes && e[cur] > 0 ; ++ i)
{
if (cap[cur][i] > flow[cur][i])
{
if (h[cur] > h[i])
{
push(cur,i);
if (label[i] == 0 && i != source && i != sink)
{
label[i]
= 1 ;
Q.push(i);
}
}
else if (Min == - 1 ) { Min = h[i];}
else { Min = min(Min,h[i]);}
}
}
if (e[cur] > 0 ) h[cur] = Min + 1 ;
else
{
label[cur]
= 0 ;
Q.pop();
}
}
}

 

转载于:https://www.cnblogs.com/one-piece/archive/2010/06/13/1758017.html

你可能感兴趣的:(最大流,最大权二分匹配,二分匹配算法模板)