网络流裸题,不过第一发写的 dinic + 当前弧优化果断超时,后来加了扩栈指令9000多ms险过,本题让我真正意识到了只掌握Dinic写法的局限性,所以学习了很久ISAP的写法,通过研究鸟神当年的博客,终于算是基本掌握qwq
写完试了一下 3000ms过掉,贴上我自己的模板
// ISAP + 当前弧优化 + GAP优化
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF = 1e9 + 7;
const int A = 1e5 + 10;
class Edge{
public:
int v,w,next;
}G[A<<1];
int head[A],cur[A],dis[A],num[A],que[A],pre[A];
int st,ed,nv,tot,Thead,Ttail;
void add(int u,int v,int w){
G[tot].v = v;
G[tot].w = w;
G[tot].next = head[u];
head[u] = tot++;
swap(u,v);
G[tot].v = v;
G[tot].w = w;
G[tot].next = head[u];
head[u] = tot++;
}
void init(){
tot = 0;
memset(head,-1,sizeof(head));
}
void Rev_bfs(){
memset(dis,-1,sizeof(dis));
memset(num,0,sizeof(num));
num[0]++;
dis[ed] = 0;
Thead = Ttail = 0;
que[Ttail++] = ed;
while(Thead < Ttail){
int u = que[Thead++];
for(int i=head[u] ;i!=-1 ;i=G[i].next){
int v = G[i].v;
if(dis[v] == -1){
dis[v] = dis[u] + 1;
num[dis[v]]++;
que[Ttail++] = v;
}
}
}
}
int ISAP(){
memcpy(cur,head,sizeof(cur));
Rev_bfs();
int flow = 0,u = pre[st] = st;
while(dis[st] < nv){
// printf("!");
if(u == ed){
int f = INF,neck;
for(int i=st ;i!=ed ;i=G[cur[i]].v){
if(f > G[cur[i]].w){
f = G[cur[i]].w;
neck = i;
}
}
for(int i=st ;i!=ed ;i=G[cur[i]].v){
G[cur[i]].w -= f;
G[cur[i]^1].w += f;
}
flow += f;
u = neck;
}
bool flag = 0;
for(int i=cur[u] ;i!=-1 ;i=G[i].next){
int v = G[i].v,w = G[i].w;
if(dis[u] == dis[v]+1 && w){
flag = 1;
cur[u] = i;
pre[v] = u;
u = v;
break;
}
}
if(!flag){
if((--num[dis[u]]) == 0) break;
int mind = nv;
for(int i=head[u] ;i!=-1 ;i=G[i].next){
int v = G[i].v,w = G[i].w;
if(w && mind > dis[v]){
cur[u] = i;
mind = dis[v];
}
}
dis[u] = mind + 1;
num[dis[u]]++;
u = pre[u];
}
}
return flow;
}
int main(){
//freopen("input","r",stdin);
int T;
scanf("%d",&T);
while(T--){
init();
int n,m;
scanf("%d%d",&n,&m);
int Min = INF,Max =-INF;
for(int i=1 ;i<=n ;i++){
int x,y;
scanf("%d%d",&x,&y);
if(x<Min){
Min = x;st = i;
}
if(x>Max){
Max = x;ed = i;
}
}
nv = n + 1;
for(int i=1 ;i<=m ;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
printf("%d\n",ISAP());
}
return 0;
}