版权声明:get busy living...or get busy dying https://blog.csdn.net/qq_41444888/article/details/88672208
https://cn.vjudge.net/problem/POJ-1273
sap优化:弧优化,sap优化(最短路思想?)
哎谁能给一份好点的模板啊
(收回说过的话,SAP真香)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 205;
struct node
{
int to, w, next;
node(int x = 0, int y = 0, int z = 0) : to(x), w(y), next(z){}
}e[maxn*2];
int n, m;
int u, v, w;
int cnt;
int head[maxn];
int gap[maxn], lev[maxn], cur[maxn], pre[maxn];
void addedge(int u, int v, int w)
{
e[cnt] = node(v, w, head[u]);
head[u] = cnt ++;
e[cnt] = node(u, 0, head[v]);
head[v] = cnt ++;
}
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
int sap(int s, int t)
{
int minflow, u, flow = 0, neck, i;
//neck每次记录瓶颈边,因为瓶颈边流过一次之后必定余量为0,而其余的不是,因此下次从neck开始
memset(gap, 0, sizeof(gap));
memset(lev, 0, sizeof(lev));
memset(pre, -1, sizeof(pre));
for(int i = 1; i <= n; i ++)
cur[i] = head[i];
u = s;
gap[0] = n;
while(lev[s] < n)
{
if(u == t)
{
minflow = inf;
for(i = s; i != t; i = e[cur[i]].to)
{
if(minflow > e[cur[i]].w)
{
neck = i;
minflow = e[cur[i]].w;
}
}
for(i = s; i != t; i = e[cur[i]].to)
{
e[cur[i]].w -= minflow;
e[cur[i]^1].w += minflow;
}
flow += minflow;
u = neck;
}
for(i = cur[u]; ~i; i = e[i].next)
if(e[i].w && lev[u] == lev[e[i].to] + 1) break;
if(i != -1)
{
cur[u] = i;
pre[e[i].to] = u;
u = e[i].to;
}
else
{
if(! --gap[lev[u]]) break;
cur[u] = head[u];
int newlevel = n;
for(i = head[u]; ~i; i = e[i].next)
if(e[i].w) newlevel = min(newlevel, lev[e[i].to]);
lev[u] = newlevel + 1;
gap[lev[u]] ++;
if(u != s) u = pre[u];
}
}
return flow;
}
int main()
{
while(scanf("%d%d", &m, &n) != EOF)
{
init();
for(int i = 1; i <= m; i ++)
{
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
printf("%d\n", sap(1, n));
}
return 0;
}
不知道对不对的自行优化代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 205;
struct node
{
int to, w, next;
node(int x = 0, int y = 0, int z = 0) : to(x), w(y), next(z){}
}e[maxn*2];
int n, m;
int u, v, w;
int cnt;
int head[maxn];
int gap[maxn], lev[maxn], cur[maxn], pre[maxn];
void addedge(int u, int v, int w)
{
e[cnt] = node(v, w, head[u]);
head[u] = cnt ++;
e[cnt] = node(u, 0, head[v]);
head[v] = cnt ++;
}
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
int sap(int s, int t)
{
int minflow, u, flow = 0, neck, i;
//neck每次记录瓶颈边,因为瓶颈边流过一次之后必定余量为0,而其余的不是,因此下次从neck开始
memset(gap, 0, sizeof(gap));
memset(lev, 0, sizeof(lev));
memset(pre, -1, sizeof(pre));
for(int i = 1; i <= t; i ++)
cur[i] = head[i];
u = s;
gap[0] = t;
while(lev[s] < t)
{
if(u == t)
{
minflow = inf;
for(i = s; i != t; i = e[cur[i]].to)
{
if(minflow > e[cur[i]].w)
{
neck = i;
minflow = e[cur[i]].w;
}
}
for(i = s; i != t; i = e[cur[i]].to)
{
e[cur[i]].w -= minflow;
e[cur[i]^1].w += minflow;
}
flow += minflow;
u = neck;
}
for(i = cur[u]; ~i; i = e[i].next)
if(e[i].w && lev[u] == lev[e[i].to] + 1) break;
if(i != -1)
{
cur[u] = i;
pre[e[i].to] = u;
u = e[i].to;
}
else
{
if(! --gap[lev[u]]) break;
cur[u] = head[u];
int newlevel = t;
for(i = head[u]; ~i; i = e[i].next)
if(e[i].w) newlevel = min(newlevel, lev[e[i].to]);
lev[u] = newlevel + 1;
gap[lev[u]] ++;
if(u != s) u = pre[u];
}
}
return flow;
}
int main()
{
while(scanf("%d%d", &m, &n) != EOF)
{
init();
for(int i = 1; i <= m; i ++)
{
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
printf("%d\n", sap(1, n));
}
return 0;
}