`
yzmduncan
  • 浏览: 330329 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

网络流之--最小点权覆盖和最大点权独立集

阅读更多

    二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。

 

    二分图最小点权覆盖

    从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。

建模:

    原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t,将s和x集合中的点相连,容量为该点的权值;将y中的点同t相连,容量为该点的权值。在新图上求最大流,最大流量即为最小点权覆盖的权值和。

 

二分图最大点权独立集

    在二分图中找到权值和最大的点集,使得它们之间两两没有边。其实它是最小点权覆盖的对偶问题。答案=总权值-最小点覆盖集。具体证明参考胡波涛的论文。

 

例:HDU1569

题意:一个m*n的棋盘,每个格子都有一个权值,从中取出某些数,使得任意两个数所在的格子没有公共边,并且所取去出的数和最大。求这个最大的值。

解:

    将格子染色成二分图,显然是求二分图的最大点权独立集。将问题转化为二分图最小点权覆盖来求解,最终结果=总权和-最大流。

/*
最大点权独立集:
转化为最小点权覆盖问题,最大点权独立集=总权值-最小点权覆盖集
最小点权覆盖:
设立源点s和t,s连边到点i,容量为i点的权值;点j连边到t,容量为j点权值;原二分图中的边容量为INF,求最大流即为最小点权覆盖。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int INF = 0x7fffffff;
const int maxv = 2600;
const int maxe = 1000000;
int n,m;
int g[55][55];
struct Edge
{
    int v;
    int next;
    int flow;
};
Edge e[maxe];
int head[maxv],edgeNum;
int now[maxv],d[maxv],vh[maxv],pre[maxv],preh[maxv];
int start,end;

void addEdge(int a,int b,int c)
{
    e[edgeNum].v = b;
    e[edgeNum].flow = c;
    e[edgeNum].next = head[a];
    head[a] = edgeNum++;
    e[edgeNum].v = a;
    e[edgeNum].flow = 0;
    e[edgeNum].next = head[b];
    head[b] = edgeNum++;
}

void Init()
{
    edgeNum = 0;
    memset(head,-1,sizeof(head));
    memset(d,0,sizeof(d));
}

int sap(int s,int t,int n)       //源点,汇点,结点总数
{
    int i,x,y;
    int f,ans = 0;
    for(i = 0; i < n; i++)
        now[i] = head[i];
    vh[0] = n;
    x = s;
    while(d[s] < n)
    {
        for(i = now[x]; i != -1; i = e[i].next)
            if(e[i].flow > 0 && d[y=e[i].v] + 1 == d[x])
                break;
            if(i != -1)
            {
                now[x] = preh[y] = i;
                pre[y] = x;
                if((x=y) == t)
                {
                    for(f = INF,i=t; i != s; i = pre[i])
                        if(e[preh[i]].flow < f)
                            f = e[preh[i]].flow;
                    ans += f;
                    do
                    {
                        e[preh[x]].flow -= f;
                        e[preh[x]^1].flow += f;
                        x = pre[x];
                    }while(x!=s);
                }
            }
            else
            {
                if(!--vh[d[x]])
                    break;
                d[x] = n;
                for(i=now[x]=head[x]; i != -1; i = e[i].next)
                {
                    if(e[i].flow > 0 && d[x] > d[e[i].v] + 1)
                    {
                        now[x] = i;
                        d[x] = d[e[i].v] + 1;
                    }
                }
                ++vh[d[x]];
                if(x != s)
                    x = pre[x];
            }
    }
    return ans;
}


void build()
{
    int i,j;
    for(i = 1; i <= m; i++)
    {
        for(j = 1; j <= n; j++)
        {
            int t = (i-1)*n+j;
            if((i+j)%2)
            {
                addEdge(start,t,g[i][j]);
                if(i>1)
                    addEdge(t,t-n,INF);
                if(i<m)
                    addEdge(t,t+n,INF);
                if(j>1)
                    addEdge(t,t-1,INF);
                if(j<n)
                    addEdge(t,t+1,INF);
            }
            else
                addEdge(t,end,g[i][j]);
        }
    }
}

int main()
{
    int i,j;
    int result;
    while(scanf("%d %d",&m,&n) != EOF)
    {
        result = 0;
        Init();
        for(i = 1; i <= m; i++)
        {
            for(j = 1; j <= n; j++)
            {
                scanf("%d",&g[i][j]);
                result += g[i][j];
            }
        }
        start = 0;
        end = n*m + 1;
        build();
        printf("%d\n",result-sap(start,end,end+1));
    }
    return 0;
}

 

 

 

分享到:
评论

相关推荐

    线性规划与网络流题解

    9 方格取数问题 二分图点权最大独立集 网络最小割 10 餐巾计划问题 线性规划网络优化 最小费用最大流 11 航空路线问题 最长不相交路径 最小费用最大流 12 软件补丁问题 最小转移代价 最短路径 13 星际转移问题 网络...

    acm入门必备

    - **独立集与覆盖集的关系:** 一个图的独立集越大,则其对应的覆盖集通常越小。这是因为独立集中的顶点互不相邻,所以可以用来覆盖更少的边。 - **独立集与支配集的关系:** 独立集与支配集在某些情况下可以重合...

    图论与网络模型

    图论与网络模型是数学模型中的一种重要类型,它将图论的概念与网络模型相结合,解决了七个常见的问题:最短路径、最小生成树、网络最大流问题、图的独立集、覆盖集与支配集问题、中国邮路问题等。 最短路径 最短...

    7.胡伯涛《最小割模型在信息学竞赛中的应用》2

    在二分图中,最小点权覆盖集问题是寻找最少的顶点集合,这些顶点可以覆盖所有的边,而最大点权独立集问题则是找尽可能多的互不相邻的顶点,使得这些顶点的权重之和最大。通过最小割模型,可以转换这些问题,利用割的...

    图论与网络模型讲义(最短路径等问题)

    本文将详细讲解几个核心概念:最短路径、最小生成树、网络最大流以及图的独立集、覆盖集与支配集问题。 **最短路径问题**: 在加权图中,寻找两个顶点间边权重之和最小的路径。常见的算法有Dijkstra算法和Floyd算法...

    kuangbin的ACM模板.pdf

    5. 最小点权覆盖集,最小化覆盖所有边所需的点的权重之和。 6. 最大点权独立集,最大化集合中点的权重和,同时任何两点间没有边连接。 字符串处理是ACM竞赛中不可或缺的部分,模板涵盖: 1. KMP算法,用于高效地...

    ACM算法模板和pku代码

    限制长度最短路,负环判连通,点权变边权,改变正负号 表达式求值 算法优先算法求表达式的值 词法分析与算法优先算法,集合运算:差集,并集,交集 矩阵乘法 线段覆盖数量 矩阵构造,nlogn矩阵乘法 2-SAT XOR ...

    目标跟踪系列-匹配-1. 匈牙利&KM匹配算法

    5. **图论问题**:如最大独立集、最小点覆盖等,KM算法可以找到最佳解决方案。 6. **市场配对**:如在婚姻市场中,寻找男女双方的最优配对,使双方满意度最大化。 7. **运输问题**:在物流领域,KM算法可以帮助...

    ACM必备内容(几乎全)!!!

    - **最小费用最大流**:在网络流问题中,除了考虑流量外,还需考虑每条边的成本,目标是最小化总成本的同时达到最大流。 - **最小费用最小流**:在确保一定流量的前提下,最小化总费用。 #### 数论 数论是计算机...

    ACM模板代码

    - **有向图最小点基(邻接阵)O(N^2)**:寻找图中最小的点基,与图的独立集问题相关。 6. **FLOYD求最小环**:通过Floyd-Warshall算法寻找图中最小的环,这个算法还可以用来计算所有对之间的最短路径。 7. **2-SAT...

    Algorithms-NA2006

    - **独立集问题**:讨论了在树中寻找最大独立集的算法。 7. **线性规划与归约**:这部分内容关注线性规划的基本原理及其在实际问题中的应用。 - **线性规划简介**:介绍了线性规划的基本概念和求解方法。 - **...

    c ACM必须掌握的算法.doc

    7. **最大团与最大独立集**:在图论中寻找最大互不相邻的顶点集合。 8. **点在多边形内的判断**:在平面几何中,确定点是否位于多边形内部。 9. **差分约束系统**:用于处理限制条件下的最优化问题。 10. **双向...

    算法概论英文版

    - **树中的独立集**:在树中找到最大数量的不相邻节点集合。 #### 八、线性规划与归约 - **线性规划**:通过优化目标函数来解决约束条件下的最大化或最小化问题。 - **网络流**:研究网络中资源流动的模型,如...

    计算机常用术语

    - **网络流(Network Flow)**:模拟物质在网络中的流动过程。 - **图的描绘(Drawing Graphs Nicely)**:美观地绘制图形。 - **树的描绘(Drawing Trees)**:以清晰的方式展示树状结构。 - **平面性检测和嵌入...

Global site tag (gtag.js) - Google Analytics