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]
题意:一个犯罪团伙打算去偷一家美术馆。 警察决定派 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; }
相关文章推荐
- URAL 1277 Cops and Thieves
- 1277. Cops and Thieves
- Ural 1277 Cops and Thieves(最小点割集/最小割)
- ural 1277. Cops and Thieves【最小割】
- ural 1277. Cops and Thieves【最小割】
- 【Ural1277】 Cops and Thieves 无向图点连通度问题
- URAL 1277 Cops and Thieves
- UVAL1277_Cops and Thieves
- URAL 1277 Cops and Thieves 最小割
- URAL 1277 Cops and Thieves 最小割 无向图点带权点连通度
- Ural 1277 - Cops and Thieves 无向图的最小点割
- UVALive 3621 Power Calculus n次幂最少需要几次乘除得到 搜索
- 我们用一个等臂天平来称物体的质量,如果我们要称的物体质量范围在1到40克(整数),请问我们最少需要几块砝码可以完成这项物体质量的称量?
- UVA 361 || Cops and Robbers (点是否在凸包内
- 我们用一个等臂天平来称物体的质量,如果我们要称的物体质量范围在1到40克(整数),请问我们最少需要几块砝码可以完成这项物体质量的称量?
- 我们用一个等臂天平来称物体的质量,如果我们要称的物体质量范围在1到40克(整数),请问我们最少需要几块砝码可以完成这项物体质量的称量?
- 通过交换相邻数来完成排序所需要的最少交换次数
- UVA 361 Cops and Robbers(凸包应用)
- UVa 361 - Cops and Robbers
- UVA 361 Cops and Robbers