HDU 3491 Thieves 拆点 最小割
来源:互联网 发布:matlab分水岭算法 编辑:程序博客网 时间:2024/05/11 01:46
题意:警察抓小偷,已知每个城市至少需要的警察人数,警察要在s到h的路上抓到全部小偷,求最少需要的警察人数
分析:求最小割,等于最大流,把每个城市拆成2个点,一个点入,一个点出,2点之间的容量为这个城市的警察人数,相连的城市加容量为INF的边,求最大流
#include <iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>#define MAXN 205#define MAXE 50000#define INF 0x7fffffffusing namespace std;struct Edge{ int to,from,cap,next;}edge[MAXE];int head[MAXN],cnt,n,m,src,des;int dep[MAXN],gap[MAXN];void init(){ memset(head,-1,sizeof(head)); cnt=0;}void addedge(int cu,int cv,int cw){ // cout<<cu<<' '<<cv<<' '<<cw<<endl; edge[cnt].from=cu;edge[cnt].to=cv;edge[cnt].cap=cw;edge[cnt].next=head[cu];head[cu]=cnt++; edge[cnt].from=cv;edge[cnt].to=cu;edge[cnt].cap=0;edge[cnt].next=head[cv];head[cv]=cnt++;}int que[MAXN];void BFS(){ memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0]=1; int L=0,R=0; dep[des]=0; que[R++]=des; int u,v; while(L!=R){ u=que[L++]; L=L%MAXN; for(int i=head[u];i!=-1;i=edge[i].next){ v=edge[i].to; if(edge[i^1].cap==0||dep[v]!=-1) continue; que[R++]=v; R=R%MAXN; ++gap[dep[v]=dep[u]+1]; } }}int cur[MAXN],stack[MAXN];int Sap(){ int res=0; BFS(); int top=0; memcpy(cur,head,sizeof(head)); int u=src,i; while(dep[src]<n){ if(u==des){ int temp=INF,inser=n; for(i=0;i!=top;++i){ if(temp>edge[stack[i]].cap){ temp=edge[stack[i]].cap; inser=i; } } for(i=0;i!=top;++i){ edge[stack[i]].cap-=temp; edge[stack[i]^1].cap+=temp; } res+=temp; top=inser; u=edge[stack[top]].from; } for(i=cur[u];i!=-1;i=edge[i].next) if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1) break; if(i!=-1){ cur[u]=i; stack[top++]=i; u=edge[i].to; }else{ if(--gap[dep[u]]==0) break; int minn=n; for(i=head[u];i!=-1;i=edge[i].next){ if(edge[i].cap==0) continue; if(minn>dep[edge[i].to]){ minn=dep[edge[i].to]; cur[u]=i; } } ++gap[dep[u]=minn+1]; if(u!=src) u=edge[stack[--top]].from; } } return res;}int main(){ int t,s,h,i,u,v,ans; scanf("%d",&t); while(t--){ init(); scanf("%d%d%d%d",&n,&m,&s,&h); for(i=1;i<=n;i++){ scanf("%d",&u); addedge(i,i+n,u); addedge(i+n,i,u); } src=s+n; des=h; while(m--){ scanf("%d%d",&u,&v); addedge(u+n,v,INF); addedge(v+n,u,INF); } n*=2; ans=Sap(); printf("%d\n",ans); } return 0;}
0 0
- HDU 3491 Thieves 拆点 最小割
- Thieves (hdu 3491 拆点 最小割)
- hdoj 3491 Thieves 【最小割 + 拆点】
- HDU 3491 Thieves | 最小割
- hdu 3491 Thieves 最小割
- hdu 3491 Thieves(最小割)
- HDU 3491 Thieves(经典拆点建图,割点)
- hdu 3491(最小割+拆点)
- HDU 3491 Thieves 【拆点+最大流】
- Thieves----简单最小割
- HDU 3491 Thieves 最小点割集+拆点==最大流(建图可贵)
- hdu 3491 Thieves(最小割拆点)
- 【HDU】3491 Thieves 最小点割集
- hdu 4289 Control【最小割+拆点】
- HDU 4289--Control【最小割 && 拆点】
- 【dinic && 拆点 && 最小割】HDU
- Ural 1277 - Cops and Thieves 无向图的最小点割
- HDU 3491 最小割
- matlab学习笔记 灰度预测
- ExtJS4加载FormPanel数据的几种方式
- 【2Dhtml5游戏框架phaser介绍3】preload,create,update
- SharePoint 2013 一些小技巧
- ACM-计算几何之Raid——poj3714
- HDU 3491 Thieves 拆点 最小割
- Android Native So加壳技术
- 一道关于大数的ACM题的讨论过程——沟通与发散思维
- 传智播客的学习记录一
- 0..0
- POJ1064 Cable master
- Doing Homework again --贪心
- C++连接Access数据库
- IE 高级设置里面一片空白,没有任何选项