zoukankan      html  css  js  c++  java
  • HDU 4280 Island Transport 又一发SAP

    终于有点SAP的感觉了。总结下模板

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int maxn=100008;
    const int INF=0x7f7f7f7f;
    struct fuck{
        int u,v,w,cap,next;
    }edge[maxn<<2];
    int head[maxn];
    int tol;
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,int w)
    {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol].cap=w;
        edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].u=v;
        edge[tol].v=u;
        edge[tol].cap=0;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    bool vis[maxn];
    int dep[maxn],gap[maxn];
    //  bfs反向构造层次图,那么只关注反向残量为0的边
    void bfs(int sour,int sink)
    {
        queue<int>  q;
        memset(vis,false,sizeof(vis));
        memset(dep,-1,sizeof(dep));
        memset(gap,0,sizeof(gap));
        q.push(sink);
        dep[sink]=0;gap[0]=1;vis[sink]=true;
        int u,v,i;
        while(!q.empty())
        {
            u=q.front();q.pop();
            for(i=head[u];i!=-1;i=edge[i].next)
            {
                v=edge[i].v;
                if(!vis[v]&&edge[i].cap==0)
                {
                    vis[v]=true;
                    dep[v]=dep[u]+1;
                    q.push(v);
                    gap[dep[v]]++;
                }
            }
        }
    }
    int cur[maxn],S[maxn];
    int last;
    // 分三个过程
    int sap(int sour,int sink)
    {
        bfs(sour,sink);
        int i,u;
        for(i=0;i<=last;i++)
            cur[i]=head[i];//当前狐
        int top=0,max_flow=0;
        u=sour;
        /*三个步骤。1从当前狐查找可行狐(残量大于0,层次差为1)
                 2 若没有找到可行狐,寻找当前节点的所有相邻点,找最小的dep修改当前点层次
                    退回到上一个点继续查找
                  3 若找到汇点,在路径中找到一条残量最小的边,以这个残量修改整个路径
                    然后从这条边的起点继续查找*/
        while(dep[sour]<last)//起点层次等于所有弧长说明没有***了
        {
            if(u==sink)
            {
                int temp=INF,inser;
                for(i=0;i<top;i++)
                {
                    if(edge[S[i]].cap<temp)
                    {
                        temp=edge[S[i]].cap;
                        inser=i;
                    }
                }
                for(i=0;i<top;i++)
                {
                    edge[S[i]].cap-=temp;
                    edge[S[i]^1].cap+=temp;
                }
                max_flow+=temp;
                top=inser;
                u=edge[S[top]].u;
            }
            if(u!=sink&&gap[dep[u]-1]==0)   break;//简直,出现断层即退出
            for(i=cur[u];i!=-1;i=edge[i].next)
                if(edge[i].cap>0&&dep[u]==dep[edge[i].v]+1)
                    break;
            if(i!=-1)
            {
                cur[u]=i;
                S[top++]=i;
                u=edge[i].v;
            }
            else
            {
                int mi=last;
                for(i=head[u];i!=-1;i=edge[i].next)
                {
                    if(edge[i].cap==0)  continue;
                    if(mi>dep[edge[i].v])
                    {
                        mi=dep[edge[i].v];
                        cur[u]=i;
                    }
                }
                --gap[dep[u]];
                dep[u]=mi+1;
                ++gap[dep[u]];
                if(u!=sour)     u=edge[S[--top]].u;
            }
        }
        return max_flow;
    }
    int main()
    {
        int i,j,n,m,u,v,w,t,x,y;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            init();
            int sour,sink;
            int mi=1e9,ma=-1e9;
            for(i=1;i<=n;i++)
            {
                scanf("%d%d",&x,&y);
                if(x<mi)
                {
                    mi=x;
                    sour=i;
                }
                if(x>ma)
                {
                    ma=x;
                    sink=i;
                }
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
            last=n;
            printf("%d
    ",sap(sour,sink));
        }
        return 0;
    }
  • 相关阅读:
    android UI 适配小节
    Android中的倒计时实现
    几种适配器&观察者&ListView之间的那点事
    Service stopSelf(int statId)和onStartcommand(Intent intent,int flags,int startId)
    java 虚函数
    java 重载和多态的区别
    小程序体验版路径以及参数携带
    微信小程序--上传图片公用组件
    微信小程序页面返回
    js兼容安卓和IOS的复制文本到剪切板
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/4756064.html
Copyright © 2011-2022 走看看