[BZOJ1163&1339]Mafia
[Baltic2008]Mafia
题目
匪徒准备从一个车站转移毒品到另一个车站,警方准备进行布控. 对于每个车站进行布控都需要一定的代价,现在警方希望使用最小的代价控制一些车站,使得去掉这些车站后,匪徒无法从原定的初始点到达目标点
INPUT
第一行输入N,M代表车站的总个数,及有多少条双向边连接它们. 2<=n<=200 , 1 <=m<=20000. 第二行给出两个数a,b,代表匪徒的出发点及目标点.1<=a,b<=N,a<>b. 再下来有N行,给出对第i个车站进行布控所需要的Money,其不超过10 000 000 再下来M行,用于描述图的结构.
OUTPUT
最少需要多少Money
SAMPLE
INPUT
5 6
5 3
2
4
8
3
10
1 5
1 2
2 4
4 5
2 3
3 4OUTPUT
5
解题报告
本命题QWQ
我的Mafia啊QWQ
其实就是个裸的最小割QWQ
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 inline int read(){ 7 int sum(0);char ch(getchar()); 8 for(;ch<'0'||ch>'9';ch=getchar()); 9 for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar()); 10 return sum; 11 } 12 struct edge{int e,w;edge *n,*rev;}*pre[405]; 13 inline void insert(int s,int e,int w){ 14 edge *tp1(new edge),*tp2(new edge); 15 tp1->e=e;tp1->w=w;tp1->rev=tp2;tp1->n=pre[s];pre[s]=tp1; 16 tp2->e=s;tp2->w=0;tp2->rev=tp1;tp2->n=pre[e];pre[e]=tp2; 17 } 18 const int inf(0x3f3f3f3f); 19 int n,m,a,b,S,T,ans,dis[405]; 20 queue<int>q; 21 inline bool bfs(){ 22 memset(dis,0,sizeof(dis));while(!q.empty())q.pop();dis[S]=1;q.push(S); 23 while(!q.empty()){ 24 int k(q.front());q.pop(); 25 for(edge *i=pre[k];i;i=i->n) 26 if(i->w&&!dis[i->e]){ 27 dis[i->e]=dis[k]+1; 28 if(i->e==T)return true; 29 q.push(i->e); 30 } 31 } 32 return false; 33 } 34 inline int dfs(int u,int f){ 35 if(u==T||!f)return f; 36 int ret(0); 37 for(edge *i=pre[u];i;i=i->n) 38 if(i->w&&dis[i->e]==dis[u]+1){ 39 int tmp(dfs(i->e,min(i->w,f-ret))); 40 i->w-=tmp;i->rev->w+=tmp;ret+=tmp; 41 if(ret==f)break; 42 } 43 return ret; 44 } 45 int main(){ 46 n=read(),m=read(),a=read(),b=read();S=0,T=(n<<1)+1; 47 insert(S,a,inf);insert(b+n,T,inf); 48 for(int i=1;i<=n;++i){int x(read());insert(i,i+n,x);} 49 for(int i=1;i<=m;++i){ 50 int x(read()),y(read()); 51 insert(x+n,y,inf);insert(y+n,x,inf); 52 } 53 while(bfs())ans+=dfs(S,inf); 54 printf("%d",ans); 55 }