1.EK
/*
poj 1273
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
#define MAXN 205
#define INF 0x3f3f3f3f
int n,m;
int flow[MAXN][MAXN],cap[MAXN][MAXN],a[MAXN],p[MAXN];
//分別爲:flow[u][v]爲<u,v>流量、cap[u][v]爲<u,v>容量、a[i]表示源點s到節點i的路徑上的最小殘留量、p[i]記錄i的前驅
//不用flow也可以,flow+1 就相當於是 cap-1
int Edmonds_Karp(int s,int t)
{
int i,u,v,sum;
sum=0;//記錄最大流量
queue<int>q;//隊列,用bfs找增廣路
while(1)
{
memset(a,0,sizeof(a));//每找一次,初始化一次
a[s]=INF;
q.push(s);//源點入隊
while(!q.empty())
{
u=q.front();
q.pop();
for(v=1;v<=m;v++)
{
if(!a[v]&&cap[u][v]>0)
//if(!a[v]&&flow[u][v]<cap[u][v])
{
p[v]=u;
q.push(v);
a[v]=min(a[u],cap[u][v]);//s-v路徑上的最小殘量
//a[v]=min(a[u],cap[u][v]-flow[u][v]);//s-v路徑上的最小殘量
}
}
}
if(a[m]==0)//找不到增廣路,則當前流已經是最大流
break;
sum+=a[m];//流加上
for(i=m;i!=s;i=p[i])// //從匯點順着這條增廣路往回走
{
cap[p[i]][i]-=a[m];//更新正向流量
cap[i][p[i]]+=a[m];//更新反向流量
//flow[p[i]][i]+=a[m];//更新正向流量
//flow[i][p[i]]-=a[m];//更新反向流量
}
}
return sum;
}
int main()
{
int v,u,w,i,ans;
while(~scanf("%d%d",&n,&m))
{
//memset(flow,0,sizeof(flow));
memset(cap,0,sizeof(cap));
for(i=0;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
cap[u][v]+=w;//注意圖中可能出現相同的邊
}
ans=Edmonds_Karp(1,m);
printf("%d\n",ans);
}
return 0;
}
2.SAP(鄰接矩陣)----來自kuangbin模板
/*
poj 1149
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
#define MAXN 105
#define INF 0x3f3f3f3f
int maze[MAXN][MAXN];
int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];
int SAP(int s,int t,int n)
{
memset(cur,0,sizeof(cur));
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
int u=pre[s]=s,maxflow=0,aug=-1;
gap[0]=n;
while(dis[s]<n){
loop:
for(int v=cur[u];v<n;v++)
{
if(maze[u][v]&&dis[u]==dis[v]+1)
{
if(aug==-1||aug>maze[u][v])
aug=maze[u][v];
pre[v]=u;
u=cur[u]=v;
if(v==t)
{
maxflow+=aug;
for(u=pre[u];v!=s;v=u,u=pre[u])
{
maze[u][v]-=aug;
maze[v][u]+=aug;
}
aug=-1;
}
goto loop;
}
}
int mindis=n-1;
for(int v=0;v<n;v++)
{
if(maze[u][v]&&mindis>dis[v])
{
cur[u]=v;
mindis=dis[v];
}
}
if((--gap[dis[u]])==0)
break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return maxflow;
}
int main()
{
int n,m,i,j,s,t,c,u,v,w,ans,gg,x;
int a[1005],vis[1005];
while(~scanf("%d%d",&m,&n))
{
memset(maze,0,sizeof(maze));
memset(vis,0,sizeof(vis));
for(i=1;i<=m;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&gg);
for(j=0;j<gg;j++)
{
scanf("%d",&x);
if(!vis[x])
{
vis[x]=i;
maze[0][i]+=a[x];
}
else
{
maze[vis[x]][i]=INF;
}
}
scanf("%d",&x);
maze[i][n+1]=x;
}
ans=SAP(0,n+1,n+2);
printf("%d\n",ans);
}
return 0;
}