hdu4289Control 最大流

来源:互联网 发布:js object 遍历 值 编辑:程序博客网 时间:2024/03/28 16:58
//给出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 ;}
0 0