• 方格取数(1)


    该题求的是 最大独立集团权值和   因为所取的点没有两点是相邻的

    所以把相邻点连起来!

    由前面二分匹配知   最大独立集团=顶点数-最小覆盖点 加上权值也是一样的

    所以最大独立集团权值和 ==总权值-最小覆盖点权值和 

    所以求出最小覆盖点权值和即可   且=最小割=最大流

    奇偶建图

    源点-奇数  奇数和所有相邻的建图   偶数 -汇点

    最大流=最小割=最小点权覆盖集=sum-最大点权独立集!

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 50+10;
    const int E_maxn = 50000 + 10;
    const int INF = 0x3fffffff;
    struct Edge
    {
        int from;
        int to;
        int cap;
        int next;
    };
    struct Edge edge[E_maxn];
    int deep[maxn*maxn];
    int cur[maxn*maxn];
    int k,n,m;
    int temp[4][2] = {-1,0, 1,0, 0,-1, 0,1};
    void addedge(int from,int to,int cap)
    {
        edge[k].from = from;
        edge[k].to = to;
        edge[k].cap = cap;
        edge[k].next = cur[from];
        cur[from] = k;
        k++;
        edge[k].from = to;
        edge[k].to = from;
        edge[k].cap = 0;
        edge[k].next = cur[to];
        cur[to] = k;
        k++;
    }
    int judge(int x,int y)
    {
        if(x>0 && x<=n && y>0 && y<=m)
        {
            return 1;
        }
        return 0;
    }
    bool BFS()
    {
        memset(deep,-1,sizeof(deep));
        queue<int> Q;
        Q.push(0);
        deep[0] = 0;
        while(!Q.empty())
        {
            int x = Q.front();
            Q.pop();
            int i;
            for(i=cur[x]; i!=-1; i=edge[i].next)
            {
                int e = edge[i].to;
                if(deep[e] == -1 && edge[i].cap > 0)
                {
                    deep[e] = deep[x] + 1;
                    Q.push(e);
                }
            }
        }
        return deep[n*m+1] != -1;
    }
    int DFS(int x,int a)
    {
        if(x == n*m+1)
        {
            return a;
        }
        int flow = 0;
        for(int i=cur[x]; i!=-1 && flow<a; i=edge[i].next)
        {
            int e = edge[i].to;
            if(deep[x] + 1 == deep[e] && edge[i].cap > 0)
            {
                int f = min(edge[i].cap,a-flow);
                f = DFS(e,f);
                flow += f;
                edge[i].cap -= f;
                edge[i^1].cap += f;
            }
        }
        if(!flow)
        {
            deep[x] = -2;//没有必要再往这个点走了
        }
        return flow;
    }
    int Dinic()
    {
        int flow = 0;
        int F=0;
        while(BFS())
        {
            while(F=DFS(0,INF))
            {
                flow += F;
            }
        }
        return flow;
    }
    int main()
    {
        while(cin>>n)
        {
            int i;
            int j;
    
            memset(cur,-1,sizeof(cur));
            k=0;
            int sum = 0;
            int num;
            for(i=1; i<=n; i++)
            {
                for(j=1; j<=n; j++)
                {
                    scanf("%d",&num);
                    sum+=num;
                    if((i+j) % 2 == 0)
                    {
                        addedge(0,(i-1)*n+j,num);
                        for(int z = 0; z<4; z++)
                        {
                            int x = i+temp[z][0];
                            int y = j+temp[z][1];
                            if(judge(x,y))
                            {
                                addedge((i-1)*n+j,(x-1)*n+y,INF);
                            }
                        }
                    }
                    else
                    {
                        addedge((i-1)*n+j,n*n+1,num);
    
                    }
                }
            }
            int ans = Dinic();
            cout<<sum-ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    java降序排列
    冒泡排序-java
    redis-并发竞争问题
    超卖问题
    算法-题目汇总-6
    算法-题目汇总-4
    算法-题目汇总-1
    算法-二分查找-1
    算法-bst-平衡搜索二叉树-1
    算法-位运算-1
  • 原文地址:https://www.cnblogs.com/bxd123/p/10397229.html
Copyright © 2020-2023  润新知