经过了几天的细心研究,终于把ISAP写出来了,直接上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define rep(i,a,b) for (int i=a;i<(b+1);i++)
using namespace std;
int n,m;
int G[300][300]={0},d[500]={0},iter[300]={0},hash[300]={0},pre[300]={0};
bool vis[300]={false};
void bfs(){
memset(d,-1,sizeof d);
memset(vis,0,sizeof vis);
queue<int> q;
q.push(n);
vis[n]=true;
d[n]=0;
while (!q.empty()){
int cur=q.front();
q.pop();
rep(i,1,n) if (!vis[i]&&G[i][cur]>0){
vis[i]=true;
d[i]=d[cur]+1;
q.push(i);
}
}
}
int augment(){//增广
int f=0x3f3f3f3f;
for (int i=n;i!=1;i=pre[i]) f=min(f,G[pre[i]][i]);
for (int i=n;i!=1;i=pre[i]){
G[pre[i]][i]-=f;
G[i][pre[i]]+=f;
}
return f;
}
int Max_flow(){
int flow=0;
bfs();
memset(hash,0,sizeof hash);
rep(i,1,n) iter[i]=1;//当前弧优化
rep(i,1,n) hash[d[i]]++;//gap 优化
int u=1;
while (d[1]<n){
if (u==n){
flow+=augment();
u=1;
}
bool advanced=false;
for (int &i=iter[u];i<=n;i++) if (G[u][i]>0&&d[u]==d[i]+1){
advanced=true;
pre[i]=u;
u=i;
break;
}
if (!advanced){//retreat
int m=n;
rep(i,1,n) if (G[u][i]>0&&~d[i]) m=min(m,d[i]);
if (--hash[d[u]]==0) break; //gap优化
d[u]=m+1;
hash[d[u]]++;
iter[u]=1;
if (u!=1) u=pre[u];
}
}
return flow;
}
int main(){
int T;
scanf("%d",&T);
rep(z,1,T){
scanf("%d%d",&n,&m);
memset(G,0,sizeof G);
rep(i,1,m){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
G[x][y]+=z;
}
printf("Case %d: %d\n",z,Max_flow());
}
return 0;
}