HLPP算法:http://xingzheqiang.blog.163.com/blog/static/20561012520127464654159/
时间复杂度: O(n2∗m−−√) (并不会证明。。。),楼教说对于这种分层图HLPP实际效率更优,不管你信不信,我反正是信了。
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<utility>
#include<iostream>
#include<algorithm>
const int maxn = 1505, maxl = 1505, maxm = 3e5+5, Nya = -1;
const int Ni[2] = {-1,1}, INF = 0x3f3f3f3f;
struct Edge
{
int v, cap, next;
Edge(){}
Edge(int v,int cap,int next):v(v),cap(cap),next(next){}
};
std::priority_queue<std::pair<int,int> > heap;
int head[maxn], el;
Edge edge[maxm<<1];
int n, m, L, S, T;
int h[maxl], e[maxn];
bool hash[maxn];
void NewEdge(int u,int v,int w)
{
edge[++el] = Edge(v,w,head[u]), head[u] = el;
}
int HLPP_MaxFlow()
{
hash[S] = hash[T] = true;
for(int i = head[S], p; i ; i = edge[i].next)
{
e[p = edge[i].v] = edge[i].cap;
edge[i+Ni[i&1]].cap += edge[i].cap;
if(!hash[p])
{
heap.push(std::make_pair(h[p], p));
hash[p] = true;
}
}
while(!heap.empty())
{
int u = heap.top().second, min = INF;
heap.pop(), hash[u] = false;
for(int i = head[u], v; i && e[u]; i = edge[i].next)
{
if(h[u] == h[v = edge[i].v] + 1 && edge[i].cap)
{
int flow = std::min(edge[i].cap, e[u]);
e[u] -= flow, edge[i].cap -= flow;
e[v] += flow, edge[i+Ni[i&1]].cap += flow;
if(!hash[v])
{
heap.push(std::make_pair(h[v],v));
hash[v] = true;
}
}
if(edge[i].cap) min = std::min(h[v], min);
}
if(e[u])
{
h[u] = min + 1;
heap.push(std::make_pair(h[u], u));
hash[u] = true;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sgu212.in","r",stdin);
freopen("sgu212.out","w",stdout);
#endif
std::cin >> n >> m >> L;
for(int i = 1; i <= n; i++)
{
scanf("%d",&h[i]);
if(h[i] == 1) S = i;
if(h[i] == L) T = i;
h[i] = L - h[i] + 1;
}
for(int i = 1, u, v, w; i <= m; i++)
{
scanf("%d%d%d",&u,&v,&w);
NewEdge(u, v, w), NewEdge(v, u, 0);
}
HLPP_MaxFlow();
for(int i = 1; i <= m; i++)
printf("%d\n",edge[i<<1].cap);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}