2012成都賽區網絡賽第二題---Control(hdu4289)

      題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4289

      題意:現在,你就是國家安全局頭頭,有一羣猖狂的小偷,在城市S偷了無數的財富,現在他們要把這些財富運到城市D去,這個國家有N個城市(包括S和D),共有M條路聯通這N個城市。爲了阻止小偷將財富從S運到D,需要在每個城市建一個關卡,就需要一定的花費,問至少需要花費多少,能阻止小偷成功的將財富運到城市D。

      思路:網絡流最小割。

代碼:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define inf 11000000
#define nMax 1005
#define mMax 100050
struct Node{
    int u,v,next;
    int c;
}edge[mMax];
int ne, head[nMax];
int cur[nMax], ps[nMax], dep[nMax],n,m,ans;
bool f[nMax],ff[nMax];
void addedge(int u, int v,int c){  
    edge[ne].u = u;
    edge[ne].v = v;
    edge[ne].c = c;
    edge[ne].next = head[u];
    head[u] = ne ++;

    edge[ne].u = v;
    edge[ne].v = u;
    edge[ne].c = 0;
    edge[ne].next = head[v];
    head[v] = ne ++;
}
int dinic(int s, int t){ 
    int tr, res = 0;
    int i, j, k, f, r, top;
    while(1){
        memset(dep, -1, sizeof(dep));
        for(f = dep[ps[0]=s] = 0, r = 1; f != r;)
            for(i = ps[f ++], j = head[i]; j; j = edge[j].next)
                if(edge[j].c && dep[k=edge[j].v] == -1){
                    dep[k] = dep[i] + 1;
                    ps[r ++] = k;
                    if(k == t){
                        f = r; break;
                    }
                }
        if(dep[t] == -1) break;
        memcpy(cur, head, sizeof(cur));
        i = s, top = 0;
        while(1){
            if(i == t){
                for(tr = inf, k = 0; k < top; k ++)
                    if(edge[ps[k]].c < tr)
                        tr = edge[ps[f=k]].c;
                for(k = 0; k < top; k ++){
                    edge[ps[k]].c -= tr;
                    edge[ps[k]^1].c += tr;
                }
                i = edge[ps[top=f]].u;
                res += tr;          
            }
            for(j = cur[i]; cur[i]; j = cur[i] = edge[cur[i]].next)
                if(edge[j].c && dep[i]+1 == dep[edge[j].v]) break;
            if(cur[i]){
                ps[top ++] = cur[i];
                i = edge[cur[i]].v;   
            }else{
                if(top == 0) break;
                dep[i] = -1;
                i = edge[ps[-- top]].u;
            }
        }
    }
    return res;
}
int main(){
    int i,a,b,N,M,ans;
    int src,des;
    int k;
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        
        scanf("%d%d",&src,&des);
        ans=inf;
        ne=2;
        memset(head,0,sizeof(head));
        for(i=1;i<=N;i++)
        {
            scanf("%d",&k);
            if(i == des)
                ans = k;
            addedge(i,i+N,k);
        }
        while(M--)
        {
            scanf("%d%d",&a,&b);
            addedge(a+N,b,inf);
            addedge(b+N,a,inf);
        }
        int fuck=dinic(src,des);
        if(fuck < ans) ans = fuck;
        cout<<ans<<endl;
    }
    return 0;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章