[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 }

 

 

转载于:https://www.cnblogs.com/USTC-ACM/archive/2012/03/21/2410524.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值