zoukankan      html  css  js  c++  java
  • pku 1459 最大流 SAP

    #include <iostream>
    #include
    <queue>
    #define msize 205 //最大顶点数目
    //#define INT_MAX 100000000
    using namespace std;
    int d[msize]; //标号
    int r[msize][msize]; //残留网络,初始为原图
    int num[msize]; //num[i]表示标号为i的顶点数有多少
    int pre[msize];
    int n,m; //m个顶点,n条边,从源点s到汇点t
    int min(int a,int b)
    {
    if(a<b) return a;
    else return b;
    }
    void init(int s,int t) //BFS计算标号,汇点t标号为0
    {
    int k;
    queue
    <int>Q;
    memset(d,
    1,sizeof(d));
    memset(num,
    0,sizeof(num));
    Q.push(t);
    d[t]
    =0;
    num[
    0]=1;
    while (!Q.empty())
    {
    k
    =Q.front(),Q.pop();
    for (int i=0;i<n+2;i++)
    {
    if (d[i]>=n+2&&r[i][k]>0)
    {
    d[i]
    =d[k]+1;
    Q.push(i);
    num[d[i]]
    ++;
    }
    }
    }
    }
    int findAlowArc(int i) //从i出发寻找允许弧
    {
    int j;
    for (j=0;j<n+2;j++) if (r[i][j]>0&&d[i]==d[j]+1) return j;
    return -1;
    }
    int reLable(int i) //重新标号
    {
    int mm=INT_MAX;
    for (int j=0;j<n+2;j++)
    if (r[i][j]>0) mm=min(mm,d[j]+1);

    return mm==INT_MAX?(n):mm;
    }
    int maxFlow(int s,int t) //从源点s出发的最大流
    {
    int flow=0,i=s,j;
    int delta; //增量
    memset(pre,-1,sizeof(pre));
    while (d[s]<n+2)
    {
    j
    =findAlowArc(i);
    if (j>=0)
    {
    pre[j]
    =i;
    i
    =j;
    if (i==t) //更新残留网络
    {
    delta
    =INT_MAX;
    for (i=t;i!=s;i=pre[i]) delta=min(delta,r[pre[i]][i]);
    for (i=t;i!=s;i=pre[i]) r[pre[i]][i] -= delta, r[i][pre[i]] += delta;
    flow
    += delta;
    }
    }
    else
    {
    int x=reLable(i); //重新标号
    num[x]++;
    num[d[i]]
    --;
    if (num[d[i]]==0) return flow; //间隙优化
    d[i]=x;
    if (i!=s) i=pre[i];
    }
    }
    return flow;
    }
    int main()
    {
    int i,j,k;
    int np,nc;
    int a,b,z;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
    {
    memset(r,
    0,sizeof(r));
    for(i=1;i<=m;i++)
    {
    scanf(
    " (%d,%d)%d",&a,&b,&z);
    r[a][b]
    =z;
    }
    for(i=1;i<=np;i++)
    {
    scanf(
    " (%d)%d",&a,&z);
    r[n][a]
    =z;
    }
    for(i=1;i<=nc;i++)
    {
    scanf(
    " (%d)%d",&a,&z);
    r[a][n
    +1]=z;
    }
    init(n,n
    +1);
    printf(
    "%d\n",maxFlow(n,n+1));
    }
    return 0;
    }

    http://blog.chinaunix.net/u3/102624/showart_2064077.html     参考模板

  • 相关阅读:
    如何根据二叉树 前序遍历 中序遍历 后序遍历 中的两种遍历来反推另一种遍历
    dijkstral改编
    纪念做出来的第一道计算几何题
    链式前向星
    一道简单树形dp
    算法进阶指南—特殊排序
    算法进阶指南二分章节的两道题
    秦皇岛winter camp 总结
    C
    一道cf水题
  • 原文地址:https://www.cnblogs.com/ACAC/p/1738742.html
Copyright © 2011-2022 走看看