uva 1277 Cops and Thieves(完成阻击所需要的最少人数)

来源:互联网 发布:鼎金网络投教中心 编辑:程序博客网 时间:2024/04/17 01:34

传送门:uva 1277 Cops and Thieves

题意:一个犯罪团伙打算去偷一家美术馆。 警察决定派 K 个人堵住所有从匪窝通向美术
馆的道路,不过他们只能驻守在沿途顶点处而不能在匪窝或美术馆,且每个点都
有一个需要警察驻守的最低人数 Ri。 问警察能否完成任务。 (2 < N <= 100, 1 < M <=10000)

思路:我们所要做的就是割掉一些边使得不能从S->T,除了起点和终点之外,其余点拆成两个点,u->u’,流量为a[u]

#include<bits/stdc++.h>using namespace std;#define INF 1e6const int maxn=100410;const int MAXM=101000;int head[maxn],tot,cur[maxn];struct Edge{    int to,next,cap,flow;}e[MAXM];int d[maxn],gap[maxn],N,S[MAXM];void init(int n){    memset(head,-1,sizeof(head));    tot=0;    N=n;}void addedge(int from,int to,int w){    e[tot].to=to,e[tot].next=head[from];    e[tot].cap=w,e[tot].flow=0;    head[from]=tot++;    e[tot].to=from,e[tot].next=head[to];    e[tot].cap=0,e[tot].flow=0;    head[to]=tot++;}void bfs(int st){    memset(d,-1,sizeof(d));    memset(gap,0,sizeof(gap));    d[st]=0,gap[0]=1;    queue<int>Q;    Q.push(st);    while(!Q.empty()){        int u=Q.front();        Q.pop();        for(int i=head[u];i!=-1;i=e[i].next){            int v=e[i].to;            if(d[v]!=-1)                continue;            d[v]=d[u]+1;            gap[d[v]]++;            Q.push(v);        }    }}int sap(int st,int ed){    memcpy(cur,head,sizeof(head));    bfs(ed);    int u=st,top=0,ans=0;    while(d[st]<N){        if(u==ed){            int Min=INF,ind;            for(int i=0;i<top;i++){                if(Min>e[S[i]].cap-e[S[i]].flow){                    Min=e[S[i]].cap-e[S[i]].flow;                    ind=i;                }            }            for(int i=0;i<top;i++){                e[S[i]].flow+=Min;                e[S[i]^1].flow-=Min;            }            top=ind;            u=e[S[top]^1].to;            ans+=Min;        }        bool flag=false;        int v;        for(int i=cur[u];i!=-1;i=e[i].next){            v=e[i].to;            if(e[i].cap>e[i].flow&&d[v]+1==d[u]){                flag=true;                cur[u]=i;                break;            }        }        if(flag){            S[top++]=cur[u];            u=v;            continue;        }        int Min=N;        for(int i=head[u];i!=-1;i=e[i].next){            v=e[i].to;            if(e[i].cap>e[i].flow&&d[v]<Min){                Min=d[v];                cur[u]=i;            }        }        gap[d[u]]--;        if(gap[d[u]]==0)            return ans;        d[u]=Min+1;        gap[d[u]]++;        if(u!=st)            u=e[S[--top]^1].to;    }    return ans;}int a[maxn];int main(){    int n,m,s,t,k;    while(scanf("%d%d%d%d%d",&k,&n,&m,&t,&s)!=EOF){        init(2*n+2);        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);            if(i!=s&&i!=t)                addedge(i,i+n,a[i]);        }        int flag=0,u,v;        for(int i=1;i<=m;i++){            scanf("%d%d",&u,&v);            if(u==s)                addedge(u,v,INF);            else                addedge(u+n,v,INF);            if(v==s)                addedge(v,u,INF);            else                addedge(v+n,u,INF);        }        //printf("%d\n",sap(s,t));        if(s==t||sap(s,t)>k)            printf("NO\n");        else            printf("YES\n");    }    return 0;}
0 0
原创粉丝点击