zoukankan      html  css  js  c++  java
  • 【BZOJ2127】happiness(最小割)

    题目做不完了,明天就要NOI了。

    题面

    http://darkbzoj.tk/problem/2127

    题解

    最小割——一个割代表一个方案。

    先把所有利益加上,然后用最小割考虑最少的失去的利益。

    这道题不用黑白染色,连$S$代表学文,连$T$代表学理。

    对于四种情况,列4个方程,5个未知数(对于解的确定有一定的不确定性,那就用好写的解)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #include<queue>
    #define ri register int
    #define N 50000
    #define INF 1000000007
    #define S 0
    #define T (n*m+1)
    using namespace std;
    
    int n,m,x,sum;
    
    struct graph {
      vector<int> to,w;
      vector<int> ed[N];
      int cur[N],d[N];
      void add_edge(int u,int v,int w1) {
        to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(0);  ed[v].push_back(to.size()-1);
      }
      void add_edges(int u,int v,int w1) {
        to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(w1);  ed[v].push_back(to.size()-1);
      }
      bool bfs() {
        queue<int> q;
        memset(d,0x3f,sizeof(d));
        d[0]=0; q.push(0);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0,l=ed[x].size();i<l;i++) {
            int e=ed[x][i];
            if (w[e] && d[x]+1<d[to[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) return limit;
        int tot=0;
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (d[to[e]]==d[x]+1 && w[e]) {
            int f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            w[e]-=f; w[1^e]+=f; 
            tot+=f; limit-=f;
            if (!limit) return tot;
          }
        }
        return tot;
      }
      int dinic() {
        int ret=0;
        while (bfs()) {
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF);
        }
        return ret;
      }
    } G;
    
    int main(){
      cin>>n>>m;
      for (ri i=1;i<=n;i++) {
        for (ri j=1;j<=m;j++) {
          cin>>x; sum+=x;
          G.add_edge(S,(i-1)*m+j,x*2);
        }
      }
      for (ri i=1;i<=n;i++) {
        for (ri j=1;j<=m;j++) {
          cin>>x; sum+=x;
          G.add_edge((i-1)*m+j,T,x*2);
        }
      }
      for (ri i=1;i<=n-1;i++) {
        for (ri j=1;j<=m;j++) {
          cin>>x; sum+=x;
          G.add_edge(S,(i-1)*m+j,x);
          G.add_edge(S,i*m+j,x);
          G.add_edges((i-1)*m+j,i*m+j,x);
        }
      }
      for (ri i=1;i<=n-1;i++) {
        for (ri j=1;j<=m;j++) {
          cin>>x; sum+=x;
          G.add_edge((i-1)*m+j,T,x);
          G.add_edge(i*m+j,T,x);
          G.add_edges((i-1)*m+j,i*m+j,x);
        }
      }
      for (ri i=1;i<=n;i++) {
        for (ri j=1;j<=m-1;j++) {
          cin>>x; sum+=x;
          G.add_edge(S,(i-1)*m+j,x);
          G.add_edge(S,(i-1)*m+j+1,x);
          G.add_edges((i-1)*m+j,(i-1)*m+j+1,x);
        }
      }
      
      for (ri i=1;i<=n;i++) {
        for (ri j=1;j<=m-1;j++) {
          cin>>x; sum+=x;
          G.add_edge((i-1)*m+j,T,x);
          G.add_edge((i-1)*m+j+1,T,x);
          G.add_edges((i-1)*m+j,(i-1)*m+j+1,x);
        }
      }
      
      cout<<(2*sum-G.dinic())/2;
    }
  • 相关阅读:
    励志
    哈佛大学用这12张图,教育了10亿人
    5分钟弄懂Docker!
    第四节:Web爬虫之pyquery解析库
    第十节:numpy之数组文件操作
    第三节:Web爬虫之BeautifulSoup解析库
    国嵌内核驱动进阶班-7-1(Ioctl设备控制)
    国嵌内核驱动进阶班-6-4 竞争与互斥(2)
    国嵌内核驱动进阶班-6-4 竞争与互斥
    C++类对象的内存结构
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11188300.html
Copyright © 2011-2022 走看看