#include
#include
#include
#define MAXN 205
#define MAXM 410
#define INT_MAX 0x7fffffff
using namespace std;
int n,m;
struct node
{
int c,next,to;
} edge[MAXM];
int cnt,head[MAXN];
void addedge(int from,int to,int c)//這裏存的還是一條有向邊
{
edge[cnt].to=to;
edge[cnt].c=c;
edge[cnt].next=head[from]; head[from]=cnt++;
edge[cnt].to=from;
edge[cnt].c=0; edge[cnt].next=head[to];
head[to]=cnt++;
}
int gap[MAXN],h[MAXN],curedges[MAXN],pre[MAXN];
int start,end;
int SAP_GAP()
{
start=1;
end=n;
//gap; h:距離標號數組;curedges:當前弧數組;pre前驅數組
int cur_flow,flow_ans=0,u,tmp,neck,i;// 初始化最大0
memset(h,0,sizeof(h));
memset(gap,0,sizeof(gap));
memset(pre,-1,sizeof(pre));
for(i=1; i<=n; i++)
curedges[i]=head[i];//初始化當前弧爲第一條鄰接邊
gap[0]=n;
u=start;
while(h[start]<</span>n)
{ if(u==end)
{ cur_flow=INT_MAX;
for(i=start; i!=end; i=edge[curedges[i]].to)
{ if(cur_flow>edge[curedges[i]].c)
{ neck=i;
cur_flow=edge[curedges[i]].c;
}
} //增廣成功,尋找瓶頸邊
for(i=start; i!=end; i=edge[curedges[i]].to)
{ tmp=curedges[i];
edge[tmp].c-=cur_flow;
edge[tmp^1].c=cur_flow;
}
flow_ans+=cur_flow;
u=neck;
}
for(i=curedges[u]; i!=-1; i=edge[i].next)
if(edge[i].c&&h[u]==h[edge[i].to]+1)
break; //尋找可行弧
if(i!=-1) //找到可行弧
{ curedges[u]=i;
pre[edge[i].to]=u;
u=edge[i].to;
}
else //未找到可行弧
{ gap[h[u]]--;
if(gap[h[u]]==0) break; //GAP優化
curedges[u]=head[u];
for(tmp=n,i=head[u]; i!=-1; i=edge[i].next)
if(edge[i].c)
tmp=min(tmp,h[edge[i].to]);
h[u]=tmp+1;
++gap[h[u]];
if(u!=start) u=pre[u];
}
}
return flow_ans;
}
void init()
{ int from,to,c;
cnt=0;
memset(head,-1,sizeof(head));
for(int i=0; i<</span>m; i++)
{ scanf("%d%d%d",&from,&to,&c);
addedge(from,to,c);
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&m,&n))
{ init();
printf("%d\n",SAP_GAP());
}
return 0;
}
code2:鏈式前向星(2)
#include
#include
#include
#define inf 0x7fffffff
using namespace std;
const int N=205;
const int M=500;//邊是雙向存的(注意不是無向)要開正常的2倍大
struct Edge
{
int v,next,w;
} edge[M];
int head[N],cnt,n,m,s=1;
int pre[N],cur[N],dis[N],gap[N];
void addedge(int u,int v,int w)//這裏存的還是一條有向邊
{ edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
int sap()
{ int flow=0,aug=inf,u;
bool flag;
memset(pre,-1,sizeof(pre));
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
for(int i=1; i<=n; i++)
cur[i]=head[i];
gap[s]=n; //初始化時全部處於gap[s]
u=pre[s]=s;
while(dis[s]<</span>n)
{ flag=0;
for(int &j=cur[u]; j!=-1; j=edge[j].next)
{ int v=edge[j].v;
if(edge[j].w>0&&dis[u]==dis[v]+1)
{
flag=1;
if(edge[j].w<</span>aug) aug=edge[j].w;
pre[v]=u;
u=v;
if(u==n) //如果到達end
{ flow+=aug;
while(u!=s)
{ u=pre[u];
edge[cur[u]].w-=aug;
edge[cur[u]^1].w+=aug;//異或是找與其配對的邊
}
aug=inf;
}
break;
}
}
if(flag) //未找到可行邊
continue;
int mindis=n;
for(int j=head[u]; j!=-1; j=edge[j].next)
{ int v=edge[j].v;
if(edge[j].w>0&&dis[v]<</span>mindis)
{ mindis=dis[v];
cur[u]=j;
}
}
if((--gap[dis[u]])==0)
break;
dis[u]=mindis+1;
gap[dis[u]]++;
u=pre[u];
}
return flow;
}
void init()
{ int from,to,c;
cnt=0;
memset(head,-1,sizeof(head));
for(int i=0;i<</span>m;i++)
{ scanf("%d%d%d",&from,&to,&c);
addedge(from,to,c);
}
}
int main()
{ while(~scanf("%d%d",&m,&n))
{
init();
printf("%d\n",sap());
}
return 0;
}
code3:鄰接矩陣
#include
#include
#include
#define M 205
using namespace std;
const int inf=~0U>>1;
int n,nb,nc,m;
int gap[M],flow[M][M],dist[M],cur[M];
int pre[M];
int source,end,s,t;
int sap()
{
s=source;
t=end;
memset(cur,0,sizeof(cur));
memset(dist,0,sizeof(dist)); memset(gap,0,sizeof(gap));
int u=pre[s]=s,maxflow=0,aug=inf;
gap[0]=n;
while(dist[s]<</span>n)
{
loop:
for(int v=cur[u];v<=n;v++)
{ if(flow[u][v]&&dist[u]==dist[v]+1)
{
cur[u]=v;
aug=min(aug,flow[u][v]);
pre[v]=u;
u=v;
if(v==t)
{ maxflow+=aug;
for(u=pre[u];v!=s;v=u,u=pre[u])
flow[u][v]-=aug,flow[v][u]+=aug;
aug=inf;
}
goto loop;
}
}
int mind=n;
for(int v=1;v<=n;v++)
if(flow[u][v]&&(mind>dist[v]))
{
cur[u]=v;
mind=dist[v];
}
if((--gap[dist[u]])==0) break;
gap[dist[u]=mind+1]++;
u=pre[u];
}
return maxflow;
}
void init()
{ int from,to,c;
memset(flow,0,sizeof(flow));//沒加這個 wa了4次
for(int i=0;i<</span>m;i++)
{
scanf("%d%d%d",&from,&to,&c);
flow[from][to]+=c;
}
source=1;
end=n;
}
int main()
{
int x,y,c;
while(~scanf("%d%d",&m,&n))
{
init();
printf("%d\n",sap());
}
return 0;
}