最大流模板(学习中)

来源:互联网 发布:诸神黄昏坐骑进阶数据 编辑:程序博客网 时间:2024/06/03 18:39

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 0x3f3f3f3fint 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-1int 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 0x3f3f3f3fint 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;}


0 0
原创粉丝点击