您的位置:首页 > 运维架构

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

2016-08-19 14:03 411 查看
传送门: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 1e6
const 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: