zoukankan      html  css  js  c++  java
  • P4313 文理分科

    题意简述

    (n imes m)个座位,每个座位上的同学可以选择文科和理科。如果((i,j))上的同学选文科,答案加(art_{i,j}),如果选理科,答案加(sci_{i,j})。如果一个位置和其上、下、左、右(不包括没人的地方)都选文或理,则答案再加上(sameart_{i,j})(samesci_{i,j}),求最大答案。

    简单口胡

    这题用最小割,因为这种两者选择的题目,显然是先把和求出来,在求出最小割减掉。
    考虑建图,首先肯定是先连所有的((S,(i,j),art_{i,j}))(((i,j),T,sci_{i,j}))
    然后((S,(i,j),sameart_{i,j}))(((i,j),T,samesci_{i,j}))
    最小割转成最大流,没了。
    难度主要在建边。

    # include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 30100;
    const int M = 240005;
    
    int n,m;
    int art[105][105];
    int sci[105][105];
    int same_art[105][105];
    int same_sci[105][105];
    int cur[N];
    
    struct edge
    {
        int u,v,w;
        int nxt;
        edge() {}
        edge(int _u,int _v,int _w) : u(_u),v(_v),w(_w) {}
    }E[M << 1];
    
    int Head[N];
    int tot = 1;
    int dep[N];
    
    void add(int u,int v,int w)
    {
        E[++tot] = edge(u,v,w);
        E[tot].nxt = Head[u];
        Head[u] = tot;
        E[++tot] = edge(v,u,0);
        E[tot].nxt = Head[v];
        Head[v] = tot;
        return;
    }
    
    int id(int x,int y)
    {
        return (x - 1) * m + y;
    }
    
    int s,t;
    
    bool bfs(void)
    {
        memset(dep,0,sizeof(dep));
        dep[s] = 1;
        queue <int> q;
        q.push(s);
        while(!q.empty())
        {
            int x = q.front();q.pop();
            for(int i = Head[x]; i ; i = E[i].nxt)
            {
                int v = E[i].v;
                if(!dep[v] && E[i].w)
                {
                    dep[v] = dep[x] + 1;
                    q.push(v);
                }
            }
        }
        return dep[t] > 0;
    }
    
    int dfs(int x,int a)
    {
        int sum = 0;
        if(x == t || a == 0) return a;
        for(int i = cur[x]; i ; i = E[i].nxt)
        {
            int v = E[i].v;
            if(dep[v] == dep[x] + 1 && E[i].w)
            {
                int tmp = dfs(v,min(a - sum,E[i].w));
                sum += tmp;
                E[i].w -= tmp;
                E[i xor 1].w += tmp;
            }
        }
        return sum;
    }
    
    int main(void)
    {
        scanf("%d%d",&n,&m);
        int SUM = 0;
        s = 0,t = n * m + 1;
        int cnt = t;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d",&art[i][j]);
                add(s,id(i,j),art[i][j]);
                SUM += art[i][j];
            }
        }
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d",&sci[i][j]);
                add(id(i,j),t,sci[i][j]);  
                SUM += sci[i][j];
            }
        }
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d",&same_art[i][j]);
                ++cnt;
                add(s,cnt,same_art[i][j]);
                add(cnt,id(i,j),2e9 + 7);
                SUM += same_art[i][j];
                if(i - 1 >= 1) add(cnt,id(i - 1,j),2e9 + 7);
                if(i + 1 <= n) add(cnt,id(i + 1,j),2e9 + 7);
                if(j - 1 >= 1) add(cnt,id(i,j - 1),2e9 + 7);
                if(j + 1 <= m) add(cnt,id(i,j + 1),2e9 + 7);
            }
        }
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                scanf("%d",&same_sci[i][j]);
                ++cnt;
                add(cnt,t,same_sci[i][j]);
                add(id(i,j),cnt,2e9 + 7);
                SUM += same_sci[i][j];
                if(i - 1 >= 1) add(id(i - 1,j),cnt,2e9 + 7);
                if(i + 1 <= n) add(id(i + 1,j),cnt,2e9 + 7);
                if(j - 1 >= 1) add(id(i,j - 1),cnt,2e9 + 7);
                if(j + 1 <= m) add(id(i,j + 1),cnt,2e9 + 7);
            }
        }
        int flow = 0;
        while(bfs()) 
        {
            for(int i = 0; i <= cnt; i++) cur[i] = Head[i];
            flow += dfs(s,2e9);
        }
        printf("%d
    ",SUM - flow);
        return 0;
    }
    
  • 相关阅读:
    DVWA-7.3 SQL Injection(SQL注入)-High
    DVWA-7.2 SQL Injection(SQL注入)-Medium-绕过引号转义
    记一次错误
    笔记3
    笔记2
    题目--猜数字
    java基础-流程控制
    Python垃圾回收机制
    @staticmethod和@classmethod的作用与区别
    java转python代码
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/14387666.html
Copyright © 2011-2022 走看看