[HDU] 3491 Thieves
1.拆点(把一个点拆成2个,边流量为警(和谐)察数,然后每条边连的时候用其中一个点的第二个点去连另一个点的第一个点,边流量为无穷大,其他边都为0,再注意下源点和汇点就可以了)
2.最大流找最小割
View Code
1 #include<stdio.h>
2 #include<stdlib.h>
3 #define MAX 100000000
4 int n,m,s,h,c[205][205],p[205];
5 int find()
6 {
7 int x,i,inque[205],que[205],head=0,tail=0;
8 memset(inque,0,sizeof(inque));
9 memset(que,0,sizeof(que));
10 que[head]=s;inque[s]=1;
11 while(head<=tail)
12 {
13 x=que[head++];
14 for(i=1;i<=2*n;i++)
15 if(!inque[i]&&c[x][i]){inque[i]=1;que[++tail]=i;p[i]=x;if(i==h)return 1;}
16 }
17 return 0;
18 }
19 int maxflow()
20 {
21 int i,j,min,flow=0;
22 memset(p,0,sizeof(p));
23 while(find(i))
24 {
25 min=MAX;
26 j=h;i=p[j];
27 while(j!=s)
28 {
29 if(min>c[i][j])min=c[i][j];
30 j=i;i=p[j];
31 }
32 j=h;i=p[j];
33 while(j!=s)
34 {
35 c[i][j]-=min;
36 c[j][i]+=min;
37 j=i;i=p[j];
38 }
39 flow+=min;
40 memset(p,0,sizeof(p));
41 }
42 return flow;
43 }
44 int main()
45 {
46 int i,x,y,ans,t;
47 scanf("%d",&t);
48 while(t>0)
49 {
50 t--;
51 memset(c,0,sizeof(c));
52 scanf("%d%d%d%d",&n,&m,&s,&h);
53 for(i=1;i<=n;i++)
54 scanf("%d",&c[i][i+n]);
55 c[s][s+n]=MAX;
56 c[h][h+n]=0;
57 for(i=1;i<=m;i++)
58 {
59 scanf("%d%d",&x,&y);
60 c[x+n][y]=c[y+n][x]=MAX;
61 }
62 ans=maxflow();
63 printf("%d\n",ans);
64 }
65 return 0;
66 }