题目大概说,一个国家有n个城市,由m条双向路相连,小偷们从城市s出发准备到h城市,警察准备在某些除了s和h外的城市布置警力抓小偷,各个城市各有警力所需的数目。问警察最少要布置多少警力才能万无一失地抓住所有小偷。

相当于就是用最小的花费让s到达不了h。这么建容量网络:

每个城市拆点连容量为需要警力数量的边,源点为s',汇点为h,原图双向边的容量设为INF。

最小割就是答案了。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 222
#define MAXM 44444
struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NV,NE,head[MAXN];
void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
}
int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
}
int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
}
int main(){
int t,n,m,s,h,a,b;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&m,&s,&h);
vs=s+n; vt=h; NV=n*+; NE=;
memset(head,-,sizeof(head));
for(int i=; i<=n; ++i){
scanf("%d",&a);
addEdge(i,i+n,a);
}
while(m--){
scanf("%d%d",&a,&b);
addEdge(a+n,b,INF);
addEdge(b+n,a,INF);
}
printf("%d\n",ISAP());
}
return ;
}

最新文章

  1. SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)
  2. Java笔记:有啥记啥
  3. iOS之触摸及手势
  4. PHP while使用
  5. yum源安装Mysql
  6. CSS 伪元素&amp;伪类
  7. JavaScript中的加法运算
  8. C++-new操作符
  9. poll实现
  10. 改进uboot,添加自定义快捷菜单
  11. wso2esb源码编译总结
  12. 我博客上的围棋js程序
  13. 不用Ajax时的传参方法
  14. 使用unity开发游戏时如觉得游戏声音太吵,点Mute Audio
  15. 中国移动物联网ONENET平台数据本地采集工具
  16. Ubuntu16.04 安装 wps (不推荐安装)
  17. HTML&amp;CSS书写规范
  18. EF使用MySql DBFirst产品的问题总结
  19. 801. Minimum Swaps To Make Sequences Increasing
  20. 如何编写makefile文件

热门文章

  1. CSS 实现垂直居中的几种方案
  2. js打印(控件)及多种方式
  3. ajax页面排序的序号问题
  4. Vmware怎样使用nat和桥接方式解决虚拟机联网问题
  5. HDU 2955 Robberies 背包概率DP
  6. make_head,,,pop_head,,,push_head,,,sort_head..
  7. ImageMagick资料
  8. nc 常用命令
  9. CSS用Id选择器在本页写样式
  10. ARGB32 to YUV12 利用 SDL1.2 SDL_ttf 在视频表面输出文本