spoj COCONUTS (最小割模型)

说一下建图过程, 虚拟源点 s,  汇点 t 。对于猜想本来是0的人i,建边(s,i,1) ,猜想为1的 建边(i, t, 1)  。对于是一对朋友的 ,建边(i,j,1) ,(j,i,1) 。由最小割的性质=最大流。故用dinic求一次最大流即可。

VIEW CODE

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<stdlib.h>
using namespace std;
const int mmax= 310;
const int mod=1000000007;
const int inf=0x3fffffff;
using namespace std;

struct node
{
    int flow;
    int en;
    int next;
}E[2*mmax*mmax];
int p[mmax];
int num;
void init()
{
    memset(p,-1,sizeof p);
    num=0;
}
void add(int st,int en,int flow)
{
    E[num].en=en;
    E[num].flow=flow;
    E[num].next=p[st];
    p[st]=num++;
    E[num].en=st;
    E[num].flow=0;
    E[num].next=p[en];
    p[en]=num++;
}

int d[mmax];
bool vis[mmax];
int qq[mmax];
int cur[mmax];
bool bfs(int st,int en)
{
    memset(vis,0,sizeof vis);
    int qcnt=0;
    qq[++qcnt]=st;
    d[st]=0;
    vis[st]=1;
    while(qcnt)
    {
        int x=qq[qcnt];
        qcnt--;
        for(int i=p[x]; i+1; i=E[i].next)
        {
            int v=E[i].en;
            if(!vis[v]&&E[i].flow)
            {
                vis[v]=1;
                qq[++qcnt]=v;
                d[v]=d[x]+1;
            }
        }
    }
    return vis[en];
}
int dfs(int st,int en,int  flow)
{
    if(st==en||flow==0)
        return flow;
    int f=0,dd;
    for(int &i=cur[st]; i+1;i=E[i].next)
    {
        int v=E[i].en;
        if(d[st]+1==d[v]&&(dd=dfs(v,en,min(flow,E[i].flow)))>0)
        {
            E[i].flow-=dd;
            E[i^1].flow+=dd;
            flow-=dd;
            f+=dd;
            if(flow==0)
                break;
        }
    }
    return f;
}
int dinic(int st,int en,int n)
{
    int flow=0;
    while(bfs(st,en))
    {
        for(int i=0;i<=n;i++)
            cur[i]=p[i];
        flow+=dfs(st,en,inf);
    }
    return flow;
}

int main()
{
    int n,m;
    while(cin>>n>>m && n+m)
    {
        init();
        int d;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&d);
            if(!d)
                add(0,i,1);
            else
                add(i,n+1,1);
        }
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d %d",&u,&v);
            add(u,v,1);
            add(v,u,1);
        }
        printf("%d\n",dinic(0,n+1,n+1));
    }
    return 0;
}
时间: 2024-09-30 10:08:30

spoj COCONUTS (最小割模型)的相关文章

最小割模型在信息学竞赛中的应用___读后的收获

在看了Amber的<最小割模型在信息学竞赛中的应用>后感觉到了自己的智障-- 我还是按照目录来,其实第一个子目录中我收获最大的还是01分数规划的内容. 01分数规划:给定n个条件,在其中选取一些条件,使得要求的目标函数达到最值. 通俗一点说:给定两个数组,a[i]表示选取i的收益,b[i]表示选取i的代价.如果选取i,定义x[i]=1否则x[i]=0.每一个物品只有选或者不选两种方案,求一个选择方案使得R=sigma(a[i]*x[i])/sigma(b[i]*x[i])取得最值,即所有选择物

2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型

题意: 有n个士兵,你可以选择让它成为战士还是法师. 有m对关系,u和v 如果同时为战士那么你可以获得a的权值 如果同时为法师,你可以获得c的权值, 如果一个为战士一个是法师,你可以获得b的权值 问你可以获得的最大权值是多少? 题解: 对每个士兵建立一个点x ,点x 向源点s 连一条边,向汇点t 连一条边, 分别表示选择两种职业,然后就可以先加上所有的贡献,通过两点关系用 最小割建模,如下图所示 设一条边的三种贡献为A, B, C,可以得到以下方程: 如果x,y都是法师,你可以获得C的权值,但是

【BZOJ 3144】 3144: [Hnoi2013]切糕 (最小割模型)

3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1764  Solved: 965 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R). 100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超

hdoj 3820 Golden Eggs 【双二分图构造最小割模型】

Golden Eggs Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 505    Accepted Submission(s): 284 Problem Description There is a grid with N rows and M columns. In each cell you can choose to put

hdu 3987 Harry Potter and the Forbidden Forest【网路流最小割模型】

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1549    Accepted Submission(s): 528 Problem Description Harry Potter notices some Death Eaters try to slip

tyvj P1209 - 拦截导弹 平面图最小割&amp;&amp;模型转化

P1209 - 拦截导弹 From admin    Normal (OI)总时限:6s    内存限制:128MB    代码长度限制:64KB 背景 Background 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 Description 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试验阶段,所以只有

Ural 1277 cops ans thieves (最小割模型)

题目地址 :http://acm.timus.ru/problem.aspx?space=1&num=1277 这里我们要拆点.把一个点拆成i,i' .如何 i,j有边 ,在建边(i,j',inf),(j,i',inf). 然后每个点点边(i',i,R[i]).这样建边以后,若要阻止 s到f的路径,那么必须破败一些边,那么我们为了是的边权最小,必须破坏边权小于inf的边,对应的就是图中拆点后的边(j'->j)  .实际上 这条边就代表了点j的点权.求最小割即是答案. 有一个需要注意的地方那个

【BZOJ 3232】圈地游戏 二分+SPFA判环/最小割经典模型

最小割经典模型指的是“一堆元素进行选取,对于某个元素的取舍有代价或价值,对于某些对元素,选取后会有额外代价或价值”的经典最小割模型,建立倒三角进行最小割.这个二分是显然的,一开始我也是想到了最小割的那个模型的但是我觉得他会不是一个圈我就否掉了,但是仔细想想的话会发现,如果是这样的话所得到的答案一定小于等于一个圈的答案(浓度),所以我们可定会得到最终答案,所以这样做是可以的,所以说要有宽松得正解的意识(泥沙俱下但沙子不影响我泥).当时我否掉最小割以后就立马去想费用流了,然后想到建图后发现那样建图虽

Codechef RIN 「Codechef14DEC」Course Selection 最小割离散变量模型

问题描述 提供中文版本好评,一直以为 Rin 是题目名字... pdf submit 题解 参考了 东营市胜利第一中学姜志豪 的<网络流的一些建模方法>(2016年信息学奥林匹克中国国家队候选队员论文) 读了之后很有感触,这里节选一段话: 最小割模型的本质是将点的集合 \(V\) 划分为两个点集 \(S,T\) ,使得 \(S \in S,T \in T\) ,且 \(S∩T=?\) 之前对最小割中边权为 \(INF\) 的边,一直理解为不允许被割,现在从另一个角度来认识,就是保证这条边所联通