zoukankan      html  css  js  c++  java
  • 【CF311E】Biologist

    题面

    https://www.luogu.org/problem/CF311E

    题解

    最小割,加点表示限制,三叉戟模型。

    不让割$->$割了没用。

    一定割$->$不割就联通。

    #include<map>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 20050
    #define S 0
    #define T (n+1)
    #define LL long long
    #define ri register int
    #define INF 1000000007
    using namespace std;
    
    int n,m,g;
    int s[N],v[N];
    
    struct graph {
      vector<int> ed[N];
      vector<int> w,to;
      int d[N],cur[N];
      void add_edge(int u,int v,int tw) {
        to.push_back(v); w.push_back(tw); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(0);  ed[v].push_back(to.size()-1);
      }
      bool bfs() {
        queue<int> q;
        memset(d,0x3f,sizeof(d));
        d[S]=0; q.push(S);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<ed[x].size();i++) {
            int e=ed[x][i];
            if (d[x]+1<d[to[e]] && w[e]) {
              d[to[e]]=d[x]+1;
              q.push(to[e]);
            }
          }
        }
        return d[T]<INF;
      }
      int dfs(int x,int limit) {
        if (x==T || limit==0) return limit;
        int sum=0; 
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (w[e] && d[x]+1==d[to[e]]) {
            int f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            sum+=f; limit-=f; 
            w[e]-=f; w[1^e]+=f;
            if (!limit) return sum;
          }
        }
        return sum;
      }
      int dinic() {
        int ret=0;
        while (bfs()) {
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF);
        }
        return ret;
      }
    } G;
    
    int main() {
      int ss,w,x,k,s2;
      scanf("%d %d %d",&n,&m,&g);
      for (ri i=1;i<=n;i++) scanf("%d",&s[i]);
      for (ri i=1;i<=n;i++) {
        scanf("%d",&v[i]);
        if (s[i]) G.add_edge(i,T,v[i]); else G.add_edge(S,i,v[i]);
      }
      int sum=0;
      int cc=n+1;
      for (ri i=1;i<=m;i++) {
        scanf("%d",&ss);
        scanf("%d",&w); sum+=w;
        scanf("%d",&k);
        ++cc; if (!ss) G.add_edge(S,cc,w); else G.add_edge(cc,T,w);
        for (ri j=1;j<=k;j++) {
          scanf("%d",&x);
          if (!ss) G.add_edge(cc,x,INF); else G.add_edge(x,cc,INF);
        }
        scanf("%d",&s2);
        if (s2) {
          if (!ss) G.add_edge(S,cc,g); else G.add_edge(cc,T,g);
        }
      }
      printf("%d
    ",sum-G.dinic());
      return 0;
    }
  • 相关阅读:
    什么是整型数据类型
    什么是布尔型(boolean)数据类型?
    PHP的八种数据类型
    php中session时间设置详解
    php中session数据库存储实例详解
    php中session临时文件和缓存说明
    php自定义Session的信息处理说明
    如何通过Session对用户操作权限进行判断的实例详解
    php中的Session是什么
    php中如何传递Session ID
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11297509.html
Copyright © 2011-2022 走看看