★ poj 2125 二分图的最小点权覆盖+输出解_二分图最小点覆盖问题方案输出_Go__boy的博客-程序员秘密

技术标签: 网络流  

Destroying The Graph
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 7104   Accepted: 2256   Special Judge

Description

Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After that Bob tries to destroy it. In a move he may take any vertex of the graph and remove either all arcs incoming into this vertex, or all arcs outgoing from this vertex. 
Alice assigns two costs to each vertex: Wi + and Wi -. If Bob removes all arcs incoming into the i-th vertex he pays Wi + dollars to Alice, and if he removes outgoing arcs he pays Wi - dollars. 
Find out what minimal sum Bob needs to remove all arcs from the graph.

Input

Input file describes the graph Alice has drawn. The first line of the input file contains N and M (1 <= N <= 100, 1 <= M <= 5000). The second line contains N integer numbers specifying Wi +. The third line defines Wi - in a similar way. All costs are positive and do not exceed 10 6 . Each of the following M lines contains two integers describing the corresponding arc of the graph. Graph may contain loops and parallel arcs.

Output

On the first line of the output file print W --- the minimal sum Bob must have to remove all arcs from the graph. On the second line print K --- the number of moves Bob needs to do it. After that print K lines that describe Bob's moves. Each line must first contain the number of the vertex and then '+' or '-' character, separated by one space. Character '+' means that Bob removes all arcs incoming into the specified vertex and '-' that Bob removes all arcs outgoing from the specified vertex.

Sample Input

3 6
1 2 3
4 2 1
1 2
1 1
3 2
1 2
3 1
2 3

Sample Output

5
3
1 +
2 -
2 +

Source

Northeastern Europe 2003, Northern Subregion

分析:就是二分图的最小点权覆盖问题,输出解的话,只要dfs即可。源点S,汇点T,将其余每个点拆成两个点,i和i+n,S和每一个i点连一条边,T点与每个i+n点连一条边,跑一遍最大流即可,对于输出解的情况,只要从S点开始dfs,标记走到的点即可。


代码:

//Dinic算法,复杂度O(n^2m)
#pragma comment(linker,"/STACK:102400000,102400000")
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long ll;   //记得必要的时候改成无符号
const int maxn=505;
const int maxm=1000005;
const int INF=1000000000;
struct EdgeNode
{
    int from;
    int to;
    int flow;
    int next;
}edge[maxm];
int head[maxn],cnt;
void add(int x,int y,int z)
{
    edge[cnt].from=x;edge[cnt].to=y;edge[cnt].flow=z;edge[cnt].next=head[x];head[x]=cnt++;
    edge[cnt].from=y;edge[cnt].to=x;edge[cnt].flow=0;edge[cnt].next=head[y];head[y]=cnt++;
    //printf("%d %d %d\n",x,y,z);
}

void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}

int S,T,n,m;
int d[maxn];

bool bfs(int S,int T)
{
    int que[maxn],iq=0,top;
    memset(d,0,sizeof(d));
    d[S]=1;
    que[iq++]=S;
    for(int i=0;i<iq;i++)
    {
        top=que[i];
        if(top==T)return true;
        for(int k=head[top];k!=-1;k=edge[k].next)
        {
            if(!d[edge[k].to]&&edge[k].flow)
            {
                que[iq++]=edge[k].to;
                d[edge[k].to]=d[top]+1;
            }
        }
    }
    return false;
}

int dfs(int now,int maxf,int T)
{
    if(now==T)return maxf;
    int ret=0,f;
    for(int k=head[now];k!=-1;k=edge[k].next)
    {
        if(edge[k].flow&&d[edge[k].to]==d[now]+1)
        {
            f=dfs(edge[k].to,min(maxf-ret,edge[k].flow),T);
            edge[k].flow-=f;
            edge[k^1].flow+=f;
            ret+=f;
            if(ret==maxf)return ret;
        }
    }
    return ret;
}

int Dinic(int S,int T)
{
    int ans=0;
    while(bfs(S,T))ans+=dfs(S,INF,T);
    return ans;
}

int a[maxn],b[maxn];
bool mark[3*maxn];

void dfs_cut(int x)
{
    mark[x]=1;
    int y;
    for(int i=head[x];i!=-1;i=edge[i].next)
    {
        y=edge[i].to;
        if(edge[i].flow&&!mark[y])
            dfs_cut(y);
    }
}

int main()
{
    int i,x,y,cs;
    while(~scanf("%d%d",&n,&m))
    {
        init(); S=0; T=2*n+1;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            add(i+n,T,a[i]);
        }
        for(i=1;i<=n;i++){
            scanf("%d",&b[i]);
            add(S,i,b[i]);
        }
        for(i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            add(x,y+n,INF);
        }
        printf("%d\n",Dinic(S,T));
        memset(mark,false,sizeof(mark));
        dfs_cut(S); cs=0;
        for(i=1;i<=n;i++)if(!mark[i])cs++;
        for(i=n+1;i<=2*n;i++)if(mark[i])cs++;
        printf("%d\n",cs);
        for(i=1;i<=n;i++)if(!mark[i])printf("%d -\n",i);
        for(i=n+1;i<=2*n;i++)if(mark[i])printf("%d +\n",i-n);
    }
    return 0;
}



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zcw1993912/article/details/38352569

智能推荐

吐血整理出来的大数据知识点,你掌握多少?_dCHENz的博客-程序员秘密

文章目录写在前面正片语言工具类Java实现线程的两种方式集合List集合ArrayListLinkedListSet集合HashSet二叉查找树TreeSetLinkedHashsetMap集合TreeMapHashTableJVM方法区:(被加载的信息,常量,静态变量编译后的代码等数据)虚拟机栈:(java方法服务,储存局部变量方法出口等)本地方法栈堆(对象实例创建,垃圾回收操作)程序计数器Java自带哪几种线程池?(4)HashMap和HashTable区别TreeSet和HashSet区别String

通过Field-symbols修改内表(转)_zhaimao的博客-程序员秘密

 report demo_field_symbols_assign_comp .DATA: BEGIN OF gs_itab,      drph(10) ,      cmsl01(17),      cmsl02(17),      sl01(17),      sl02(17),      END OF gs_itab.DATA: gt_ita1 LIKE gs_itab OCCUR

openstack对接对象存储swift_openstack 对接对象存储_Mediocre_person的博客-程序员秘密

对象存储服务的基本概念在了解swift服务之前首先要明确一下三个基本概念:Account: 出于访问安全性考虑,使用Swift系统,每个用户必须有一个账号(Account)。Container: Swift中的container可以类比Windows操作系统中的文件夹或者Unix类操作系统中的目录,用于管理数据,所不同的是container不能嵌套。Object: Object(对象)是Swift中的基本存储单元。Account、Container、Ob...

页面回到顶部html,页面回到顶部的两种方法_华语科幻网的博客-程序员秘密

一、a 标签链接 Id 的方法我是顶部回到顶部此种方法没什么特效过程,几乎是直接到顶。二、构造滚动动画页面回到顶部.gif页面回到顶部.box {width: 100px;height: 100px;background-color: #7bef32;position: fixed;right: 20px;top: 7000px;text-align: center;line-height: 10...

《推荐系统开发实战》之基于用户行为特征的推荐算法介绍和案例实战开发_搜索与推荐Wiki的博客-程序员秘密

转载请注明出处:http://blog.csdn.net/gamer_gyt博主微博:http://weibo.com/234654758Github:https://github.com/thinkgamer公众号:搜索与推荐Wiki个人网站:http://thinkgamer.github.io推荐系统的受众对象为用户,只有明白用户的意图,才能给用户推荐更好的内容。基于用户行为特...

C++ stringstream 类的用法_stringstream 头文件_DNFM的博客-程序员秘密

(转自:https://blog.csdn.net/nwpu_yike/article/details/22100615)一、类型转换——数字-&amp;gt;字符串C++ stringstream 类是一种十分有用的类,特别是当我们需要在程序中使用字符串和数字数据互相转换的时候。要想在程序中使用 stringstream 类,我们需要在源程序文件中包含头文件include&amp;lt;sstream&amp;...

随便推点

学习笔记(1):零基础掌握 Python 入门到实战-列表与元祖到底该用哪个?(三)..._神者的博客-程序员秘密

【为什么学Python】 Python 是当今非常热门的语言之一,2020年的 TIOBE 编程语言排行榜中 ,Python名列第一,并且其流行度依然处在上升势头。 在2015年的时候,在网上还经常看到学Python还是学R的讨论,那时候老齐就选择了Python,并...

关于uniapp的下拉刷新,上拉加载的使用_uni-app 上拉加载更多 下拉刷新_c_磊的博客-程序员秘密

uniapp是基于vue生态的,兼容多端的解决方案的一个框架。其编码风格和原生的信微信小程序有极为相似。uniapp可以轻松实现下拉刷新和上拉加载的效果,在实际应用中,对于我们对列表的分页处理,很友好。前期准备1.因为我们要做这个效果需要后端的接口分页支持,所以我们需要模拟数据(mock)创建文件夹api,api文件夹中创建mock.js。export function apiGoods(pageNum, pageSize, isGoodsEdit) { console.log('参数-

i.MX6ULL移植NXP官方Linux内核imx_5.4.47_2.2.0_nxp官方提供的linux内核_海上没有钢琴师o的博客-程序员秘密

我们使用构建的根文件系统启动以后会发现,输入命令的时候命令行前面一直都是“#”,如果我们进入到某个目录的话前面并不会显示当前目录路径。使用百问网提供的4.9.88版本的设备树,也就是6ullPRO开发板的设备树文件。(2)下载有百问网提供的gitee上的修改过的内核,然后reset到原来的分支即可。我们再来看看官方的dts,可以看到,真正描述官方evk板子外设的设备树文件是。从emmc启动根文件系统,然后用tftp下载内核和设备树,bootz启动。然后将老版本的设备树复制过来,然后编译。

CodeForces 230A Dragons(贪心)_Hot_Summer_Days的博客-程序员秘密

Dragonstime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputKirito is stuck on a level of the MMORPG he is playing now. To move on in the gam

Restful API, Restful风格是什么? 个人简单总结_不知道restful风格还面什么试_Shawn Jeon的博客-程序员秘密

Restful API个人简单理解Restful风格是什么?需用Restful的理由?Restful风格是什么?Restful的每个接口都是唯一标识, 定位资源.Restful不是标准也不是协议, 只是操作资源的架构风格, 是一种面向资源服务的API设计方式.Restful决定做何种资源操作是由 Http Method决定, Rest主要使用4种方法请求 GET(查询), POST(添加...

R语言将数据拆分为测试集和_R语言科研基础知识:把基因表达数据随机分为训练集和和测试集..._weixin_39890814的博客-程序员秘密

将数据集分为训练集和和测试方法方案一:library(ISLR)attach(Smarket)smp_siz=floor(0.75*nrow(Smarket))#createsavaluefordividingthedataintotrainandtest.Inthiscasethevalueisdefinedas75%ofthe...

推荐文章

热门文章

相关标签