zoukankan      html  css  js  c++  java
  • poj3469 最小割

    最大流之后S集合与T集合不在相连,即s不能到达T中的点。 

    对于同一个模块,Ai,Bi,Ai与源点相连,Bi与汇点相连。不同CPU间消耗的模块,相连。

    由于最后模块只能在一个CPU中运行,所以要么与源点相连,要么与汇点相连,所以可看做最小割模型。

    我原来的Dinic模板,不是多路增广,所以超时。然后向大神学习了一下,就用现在这个模板,快很多很多。

    即是用一次增广代替了多次增广,到一个节点时就一次性地把与其相邻的所有边翻出来求增广的和,如果和为零,代表它已增广不出什么了,把这个点废掉即可。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define maxn 20010
    #define Emaxn 201000
    #define INF 99999999
    using namespace std;
    struct node
    {
        int to;
        int v;
        int flag;
        int next;
    }edge[(Emaxn+maxn)*4];
    int pre[maxn],vis[maxn],index,n;
    void add(int x,int y,int z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].flag=index+1;
        edge[index].next=pre[x];
        pre[x]=index++;
        edge[index].to=x;
        edge[index].v=0;
        edge[index].flag=index-1;
        edge[index].next=pre[y];
        pre[y]=index++;
    }
    void init()
    {
        index=1;
        memset(pre,-1,sizeof(pre));
    }
    int dfs(int u,int low)//此处增加used值表示当前使用了多少
    {
        int i,used=0;
        if(u==n+1)
            return low;
        for(i=pre[u];i!=-1&&used<low;i=edge[i].next)
        {
            if(vis[edge[i].to]==vis[u]+1&&edge[i].v)
            {
                int a=dfs(edge[i].to,min(low-used,edge[i].v));
                edge[i].v-=a;
                edge[edge[i].flag].v+=a;
                used+=a;
                //原来此处返回导致不停增广,而现在更具used值多次增广,知道无法增广为止,节省很多时间。
            }
        }
        if(!used)//如果当前的路不能增广了,该点就不需要被访问。
            vis[u]=-1;
        return used;
    }
    int BFS()
    {
        int i;
        queue<int>q;
        memset(vis,-1,sizeof(vis));
        vis[0]=0;
        q.push(0);
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            for(i=pre[t];i!=-1;i=edge[i].next)
            {
                if(vis[edge[i].to]<0&&edge[i].v>0)
                {
                    vis[edge[i].to]=vis[t]+1;
                    q.push(edge[i].to);
                }
            }
        }
        if(vis[n+1]>0)return 1;
        return 0;
    }
    int main()
    {
        int i,m;
        while(~scanf("%d%d",&n,&m))
        {
            init();
            for(i=1;i<=n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                add(0,i,x);
                add(i,n+1,y);
            }
            for(i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
                add(y,x,z);
            }
            int ans=0;
            while(BFS())
            {
                while(1)
                {
                    int a=dfs(0,INF);
                    if(!a)break;
                    ans+=a;
                }
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/sweat123/p/4869506.html
Copyright © 2011-2022 走看看