hdu4289Control 最大流

//给出n个点,m条双向边
//每个点都有其对应的权值,问最少需要去除多少
//点使得图不连通
//对于每一个点进行拆点,然后求其最小割就行
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std ;
const int maxn = 10010 ;
const int inf = 0x3f3f3f3f;
int st = 0 ;int en = 1001 ;
int dis[maxn];
struct Edge
{
    int v ;int next;
    int w ;
}edge[maxn*maxn] ;
int head[maxn] , nedge ;

void addedge(int u , int v , int w)
{
    edge[nedge].v = v ;
    edge[nedge].w = w ;
    edge[nedge].next = head[u] ;
    head[u] = nedge++ ;
    edge[nedge].v = u ;
    edge[nedge].w = 0 ;
    edge[nedge].next = head[v] ;
    head[v] = nedge++ ;
}
bool bfs()
{
    queue<int> que ;
    memset(dis , -1 ,sizeof(dis)) ;
    dis[st] = 0 ;
    que.push(st) ;
    while(que.size())
    {
        int u = que.front() ;
        que.pop() ;
        for(int i = head[u]; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v ;
            if(edge[i].w > 0 && dis[v] < 0)
            {
                dis[v] = dis[u] + 1 ;
                que.push(v) ;
            }
        }
    }
    if(dis[en] > 0)
    return true ;
    return false ;
}
int dfs(int x,int mx)
{
    if(x==en)
    return mx;
    int i;
    int ans=0;
    int a;
    for(i=head[x];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w))))
        {
            edge[i].w -= a;
            edge[i^1].w += a;
            ans += a;
            mx -= a;
            if(!mx)
            break;
        }
    }
    if(!ans)
    dis[x] = -1; 
    return ans;
}
int main()
{
    //freopen("in.txt" , "r" ,stdin) ;
    int n , m ;
    while(~scanf("%d%d" , &n , &m))
    {
        memset(head , -1 , sizeof(head)) ;
        nedge = 0 ;
        scanf("%d%d" , &st , &en) ;
        st = st*2 - 1;
        en = 2*en ;
        for(int i = 1;i <= n;i++)
        {
            int tmp ;
            scanf("%d" , &tmp) ;
            addedge(i*2-1 , i*2 ,tmp);
        }
        for(int i = 1;i <= m;i++)
        {
            int u , v ;
            scanf("%d%d" , &u , &v) ;
            addedge(u*2 , v*2-1 , inf) ;
            addedge(v*2 , u*2-1 , inf) ;
        }
        int ans = 0 ;
        int res ;
        while(bfs())
        {
            while(res = dfs(st , inf))
            ans += res ;
        }
        printf("%d\n" ,ans) ;
    }
    return 0 ;
}

你可能感兴趣的:(hdu4289Control 最大流)