• poj 1149 最大流构图


    基本规律:

    规律1. 如果几个结点的流量的来源完全相同,则可以把它们合并成一个。
    规律2. 如果几个结点的流量的去向完全相同,则可以把它们合并成一个。
    规律3. 如果从点u到点v有一条容量为∞的边,并且点v除了点u以外没有别的流量来源,则可以把这两个结点合并成一个。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 205;
    const int INF = 0x3f3f3f3f;
    
    int cap[maxn][maxn];
    int flow[maxn][maxn];
    int ansf;
    int n;
    int s,t;
    
    void EK(){
        ansf = 0;
        int p[maxn];
        memset(flow,0,sizeof(flow));
        queue<int> Q;
        while(!Q.empty())  Q.pop();
        int res[maxn];
        while(true){
            memset(p,0,sizeof(p));
            p[s] = s;
               memset(res,0,sizeof(res));
            res[s] = INF;
            Q.push(s);    
             while(!Q.empty()){
                 int u = Q.front();  Q.pop();
                for(int v=1;v<=n+1;v++){
                    if(!res[v] && cap[u][v] > flow[u][v]){
                         p[v] = u;
                         Q.push(v);
                         res[v] = min(res[u],cap[u][v] - flow[u][v]); //printf("%d %d\n",u,res[v]);
                  }
               }    
           }    //printf("***  %d\n",res[t]);
           if(res[t] == 0)  break;
           for(int i=t;i!=s;i=p[i]){
               flow[p[i]][i] += res[t];  
               flow[i][p[i]] -= res[t];
            }
            ansf += res[t];  //printf("HH**  %d\n",ansf);
         }
         return;
    }
    int main()
    {
        //if(freopen("input.txt","r",stdin)== NULL)  {printf("Error\n"); exit(0);}
        int N,M,A;
        cin>>M>>N;
        s = 0; t = N+1;
        n = N ;
        memset(cap,0,sizeof(cap));    
        int c[1005];
        for(int i=1;i<=M;i++){
            cin>>c[i]; 
        }
        
        int d[maxn];
        int a[1005];
        memset(a,0,sizeof(a));
        for(int i=1;i<=N;i++){
            cin>>A;
            for(int j=1;j<=A;j++){
                int b; 
                cin>>b;
                if(!a[b]){
                     cap[s][i] += c[b];
                     a[b] = i;
                } 
                else{
                     cap[a[b]][i] = INF;
                     a[b] = i;
                }
            }
            cin>>d[i];
        }  
        for(int i=1;i<=N;i++){
            cap[i][t] = d[i];           
        }  
            EK();
            printf("%d\n",ansf);           
        return 0;
    }
  • 相关阅读:
    bzoj3280
    bzoj3876
    洛谷 p1625
    bzoj1407
    bzoj1227
    bzoj1477 && exgcd学习笔记
    bzoj1345
    c#程序的config文件问题
    思维角度的重要性
    python异步初步窥探
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3103502.html
Copyright © 2020-2023  润新知