zoukankan      html  css  js  c++  java
  • BZOJ1163&BZOJ1339[Baltic2008]Mafia——最小割

    题目描述

    匪徒准备从一个车站转移毒品到另一个车站,警方准备进行布控. 对于每个车站进行布控都需要一定的代价,现在警
    方希望使用最小的代价控制一些车站,使得去掉这些车站后,匪徒无法从原定的初始点到达目标点

    输入

    第一行输入N,M代表车站的总个数,及有多少条双向边连接它们. 
    2<=n<=200 , 1 <=m<=20000. 
    第二行给出两个数a,b,代表匪徒的出发点及目标点.1<=a,b<=N,a<>b. 
    再下来有N行,给出对第i个车站进行布控所需要的Money,其不超过10 000 000 
    再下来M行,用于描述图的结构.

    输出

    最少需要多少Money

    样例输入

    5 6
    5 3
    2
    4
    8
    3
    10
    1 5
    1 2
    2 4
    4 5
    2 3
    3 4

    样例输出

    5
     
     
      题意就是让删除一些点使得源点和汇点不联通且删除点权和最小,将每个点拆成一个入点和一个出点,两点间边权为原来点的点权,然后建双向边,就把问题转换成了求网络最小割。
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    int next[6000001];
    int to[6000001];
    int val[6000001];
    int head[6000001];
    int tot=1;
    int q[6000001];
    int n,m;
    int S,T;
    int x,y;
    int k1,k2;
    int ans;
    int d[6000001];
    const int INF=0x3f3f3f3f;
    void add(int x,int y,int v)
    {
        tot++;
        next[tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        val[tot]=v;
        tot++;
        next[tot]=head[y];
        head[y]=tot;
        to[tot]=x;
        val[tot]=0;
    }
    bool bfs(int S,int T)
    {
        int r=0;
        int l=0;
        memset(d,-1,sizeof(d));
        q[r++]=S;
        d[S]=0;
        while(l<r)
        {
            int now=q[l];
            for(int i=head[now];i;i=next[i])
            {
                if(d[to[i]]==-1&&val[i]!=0)
                {
                    d[to[i]]=d[now]+1;
                    q[r++]=to[i];
                }
            }
            l++;
        }
        if(d[T]==-1)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    int dfs(int x,int flow)
    {
        if(x==T)
        {
            return flow;
        }
        int now_flow;
        int used=0;
        for(int i=head[x];i;i=next[i])
        {
            if(d[to[i]]==d[x]+1&&val[i]!=0)
            {
                now_flow=dfs(to[i],min(flow-used,val[i]));
                val[i]-=now_flow;
                val[i^1]+=now_flow;
                used+=now_flow;
                if(now_flow==flow)
                {
                    return flow;
                }
            }
        }
        if(used==0)
        {
            d[x]=-1;
        }
        return used;
    }
    void dinic()
    {
        while(bfs(S,T)==true)
        {
            ans+=dfs(S,0x3f3f3f);
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        scanf("%d%d",&k1,&k2);
        S=k1;
        T=n+k2;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            add(i,n+i,x);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(n+x,y,INF);
            add(n+y,x,INF);
        }
        dinic();
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    docker network
    mongodb索引
    docker中管理数据
    mysql表备份及还原
    Find and run the whalesay image
    Learn about images & containers
    docker installation on ubuntu
    【转载】熟练利用google hacking来辅助我们快速渗透
    xmind常用快捷键
    漏洞挖掘基础
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9303001.html
Copyright © 2011-2022 走看看