• poj3436网络流之最大流拆点


    这题看了半天看不懂题意。。。还是看的网上题意写的

    加一个源点一个汇点,把每个点拆成两个,这两个点的流量是v,其他联通的边都设为无穷大

    输入没有1的点就与源点连接,输出只有1的点就与汇点连接

    还有这个输出技巧,因为每条反向弧初始容量设置为0,因此完成增广之后,反向弧的容量即为路径。

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define pi acos(-1)
    #define ll long long
    #define mod 10007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    const double g=10.0,eps=1e-9;
    const int N=200+5,maxn=200+5,inf=0x3fffff;
    
    int a[N][20];
    int s,t,n,p,pre[N];
    bool vis[N];
    int c[N][N];
    bool bfs()
    {
        memset(pre,0,sizeof pre);
        memset(vis,0,sizeof vis);
        vis[s]=1;
        queue<int>q;
        q.push(s);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            if(x==t)return 1;
            for(int i=0;i<=2*n+1;i++)
            {
                if(!vis[i]&&c[x][i])
                {
                    vis[i]=1;
                    q.push(i);
                    pre[i]=x;
                }
            }
        }
        return 0;
    }
    int max_flow()
    {
        int ans=0;
        while(1){
            if(!bfs())break;
            int minn=inf;
            for(int i=t;i!=s;i=pre[i])
                minn=min(minn,c[pre[i]][i]);
            for(int i=t;i!=s;i=pre[i])
            {
                c[pre[i]][i]-=minn;
                c[i][pre[i]]+=minn;
            }
            ans+=minn;
        }
        cout<<ans<<" ";
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
     //   cout<<setiosflags(ios::fixed)<<setprecision(2);
        while(cin>>p>>n){
            memset(c,0,sizeof(c));
            for(int i=1;i<=n;i++)
            {
                cin>>c[i][i+n];
                for(int j=1;j<=p;j++)cin>>a[i][j];
                for(int j=1;j<=p;j++)cin>>a[i+n][j];
            }
            for(int i=1;i<=n;i++)
            {
                bool flag=1;
                for(int j=1;j<=p;j++)
                    if(a[i][j]==1)
                    {
                        flag=0;
                        break;
                    }
                if(flag)c[0][i]=inf;
                flag=1;
                for(int j=1;j<=p;j++)
                    if(a[i+n][j]!=1)
                    {
                        flag=0;
                        break;
                    }
                if(flag)c[i+n][2*n+1]=inf;
            }
            for(int i=n+1;i<=2*n;i++)//前驱
            {
                for(int j=1;j<=n;j++)//后继
                {
                    bool flag=1;
                    for(int l=1;l<=p;l++)
                    {
                        if(a[j][l]+a[i][l]==1)
                        {
                            flag=0;
                            break;
                        }
                    }
                    if(flag)c[i][j]=inf;
                }
            }
        /*    for(int i=0;i<=2*n+1;i++)
            {
                for(int j=0;j<=2*n+1;j++)
                    cout<<c[i][j]<<" ";
                cout<<endl;
            }*/
            s=0;t=2*n+1;//t是汇点
            max_flow();
            int cnt=0,a1[N],a2[N],a3[N];
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i!=j&&c[j][i+n]>0)
                    {
                        ++cnt;
                        a1[cnt]=i;
                        a2[cnt]=j;
                        a3[cnt]=c[j][i+n];
                    }
                }
            }
            cout<<cnt<<endl;
            for(int i=1;i<=cnt;i++)
                cout<<a1[i]<<" "<<a2[i]<<" "<<a3[i]<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    POJ3468 A Simple Problem with Integers(线段树成段增减,区间求和)
    HDU1698 Just a Hook(线段树成段替换、区间求和,延迟标记的应用)
    HDU2795 Billboard(线段树基础题单节点更新区间查询)
    HDU1754 I Hate It(线段树基础题单节点更新区间查询)
    HDU5410 CRB and His Birthday(完全背包)
    HDU1166 敌兵布阵(线段树基础题单节点更新区间查询)
    cf C. Bombs
    cf B. Resort
    cf B. Color the Fence
    cf B. Little Dima and Equation
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/6890741.html
Copyright © 2020-2023  润新知