//题目类型:纯最大流 //算法实现:ISAP算法(邻接表实现) #include<iostream> #include<cstdio> //#include<conio.h> #include<string.h> using namespace std; const int maxn=201; const int maxm=201; struct node { int x,y,f,op,next; //x起点,y终点,f容量,next是以x为起点的上一条边在g中的位置,op是反向边在g中的下标位置 }g[maxm*2]; //first[]存储的是以x为起点的最后一条边的在数组g中的下标 //sumd[]用于记录表示标号为i的顶点数有多少个,用于间隙优化 //now[]临时记录以x为起点的最后一条边在数组g中的下标 int first[maxn],now[maxn],sumd[maxn]; int ncount; //代表结点的总数 int dis[maxn],fanhui[maxn],pre[maxn],tot; //dis[]用于记录距离标号,pre[i]记录i的前驱在g[]中的位置,tot记录边的总数 void add(int x,int y,int c) { tot++; //tot记录边的总数 g[tot].x=x; g[tot].y=y; g[tot].f=c; g[tot].op=tot+1; //反向边在g中的下标位置 g[tot].next=first[x]; //记录以x为起点的上一条边在g中的下标位置 first[x]=tot; //以x为起点的边的位置 tot++; //反向边 g[tot].x=y; g[tot].y=x; g[tot].f=0; //反向边的初始网络流为0 g[tot].op=tot-1; g[tot].next=first[y]; first[y]=tot; } //ISAP算法 int maxflow(int src,int des) { int i,flow,t,j,tempmin; //i,j用于标识结点,t用于标识结点在g中的位置 bool flag; //用于标识是否找到了允许路径 int sumFlow; memset(dis,0,sizeof(dis)); //初始化dis为0 memset(sumd,0,sizeof(sumd)); for(i=1;i<=ncount;i++) now[i]=first[i]; sumd[0]=ncount; //标号为0的结点有ncount个 sumFlow=0; //sumFlow记录最大流,初始化为0 i=src; //i初始化为起点 flow=10000000; while(dis[src]<ncount) { fanhui[i]=flow; flag=false; t=now[i]; while(t!=0) //寻找允许路径 { j=g[t].y; if((g[t].f>0)&&(dis[j]+1==dis[i])) //允许弧 { flag=true; pre[j]=t; now[i]=t; if(g[t].f<flow) //找到允许增量 flow=g[t].f; i=j; if(i==ncount) //找到了允许路径 { sumFlow+=flow; while(i!=src) //修改残余网络 { g[pre[i]].f-=flow; //正向边 g[g[pre[i]].op].f+=flow; //反向边 i=g[pre[i]].x; } flow=10000000; } break; } t=g[t].next; } if(flag) continue; //没有找到允许路径 tempmin=ncount-1; t=first[i]; while(t!=0) { if((g[t].f>0)&&(dis[g[t].y]<tempmin)) { tempmin=dis[g[t].y]; now[i]=t; } t=g[t].next; } sumd[dis[i]]--; if(sumd[dis[i]]==0) break; //间隙优化 dis[i]=tempmin+1; //此处别忘+1,因为d[i]=tempmin{d[j]+1|(i,j)在残留网络中} sumd[dis[i]]++; if(i!=src) { i=g[pre[i]].x; flow=fanhui[i]; } } return sumFlow; } int main() { //freopen("1.txt","r",stdin); int i,j; int N,M; int x,y,c; int src,des; //src是起点,des是终点 while(scanf("%d%d",&N,&M)!=-1) { memset(first,0,sizeof(first)); //初始化first src = 1; des = M; ncount = M; tot = 0; //tot初始化为0 for(i=0;i<N;++i) { cin>>x>>y>>c; add(x,y,c); } printf("%d\n",maxflow(src,des)); } //getch(); return 0; }