Thieves

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 1758 Accepted Submission(s): 821

Problem Description
In the kingdom of Henryy, there are N (2 <= N <= 100) cities, with M (M <= 10000) two-direct ways connecting them.
A group of thieves from abroad plan to steal the metropolitan museum in city H (It has not been demolished). However, the brave, brilliant, bright police in the kingdom have known this plan long before, and they also plan to catch the thieves. The thieves are in the city S at present. The police try to catch them on their way from S to H. Although the thieves might travel this way by more than one group, our excellent police has already gather the statistics that the number of the people needed in city I (1<=I<=N) to arrest the thieves.
The police do not want to encounter the thieves in either city S or city H.
The police finish the task with the minimum number of people. Do you know the exact number?

Input
The first line contains an integer T (T <= 10), indicating the number of the test cases.
The first line of each test case has four integers: N, the number of the cities; M, the number of the roads; S (1<=S<=N), the label of city S; H (1<=T<=N, S≠H), the label of city H.
The second line contains N integers, indicating the number of people needed in each city. The sum of these N integers is less than 10000.
Then M lines followed, each containing two integers x and y, indicating that there is a two-direct roads between city x and y. Notices that no road between city S and H.
A blank line is followed after each test case.

Output
For each test case, output a single integer in a separate line, indicating the minimum number of people the police used.

Sample Input
1
5 5 1 5
1 6 6 11 1
1 2
1 3
2 4
3 4
4 5

Sample Output
11

Source
2010 ACM-ICPC Multi-University Training Contest(6)——Host by BIT


很简单的一道最小割,因为我们在城市放人,直接把城市拆点即可,然后城市到城市之间流量为INF,跑最大流即可。

注意初末两个城市之间不能割。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e3+10,M=1e5+10;
const int inf=0x3f3f3f3f;
int T,n,m,s,t,h[N],val[N];
int head[N],nex[M],to[M],w[M],tot;
inline void ade(int a,int b,int c){
	to[++tot]=b; w[tot]=c; nex[tot]=head[a]; head[a]=tot;
}
inline void add(int a,int b,int c){
	ade(a,b,c);	ade(b,a,0);
}
inline int bfs(){
	memset(h,0,sizeof h); queue<int> q;	q.push(s);	h[s]=1;
	while(q.size()){
		int x=q.front();	q.pop();
		for(int i=head[x];i;i=nex[i]){
			if(w[i]&&!h[to[i]]){
				h[to[i]]=h[x]+1;	q.push(to[i]);
			}
		}
	}
	return h[t];
}
int dfs(int x,int f){
	if(t==x)	return f;	int fl=0;
	for(int i=head[x];i&&f;i=nex[i]){
		if(w[i]&&h[to[i]]==h[x]+1){
			int mi=dfs(to[i],min(w[i],f));
			w[i]-=mi; w[i^1]+=mi; fl+=mi; f-=mi;
		}
	}
	if(!fl)	h[x]=-1;
	return fl;
}
inline int dinic(){
	int res=0;
	while(bfs())	res+=dfs(s,inf);
	return res;
}
signed main(){
	scanf("%d",&T);
	while(T--){
		tot=1;	memset(head,0,sizeof head);
		scanf("%d %d %d %d",&n,&m,&s,&t); s+=n;
		for(int i=1;i<=n;i++)	scanf("%d",&val[i]),add(i,i+n,val[i]);
		while(m--){
			int a,b;	scanf("%d %d",&a,&b);	add(a+n,b,inf);	add(b+n,a,inf);
		}
		printf("%d\n",dinic());
	}
	return 0;
}