pku 1149
这题网络流 还是有些要说的
以顾客为节点编号1到n,猪圈也是节点编号n+1到n+m,原点s 为0,汇点为n+m+1;
i 有 j的钥匙 则增加边 i-j 容量为inf
设访问第i号节点的依次为顾客 p1,p2,p3,..px;
则增加边 p2-p1,p3-p2,p4-p3....容量为inf
然后就是贴模板了~~
这题的节点最多有1102个 竟然不超时……
1
#include <iostream>
2
using namespace std;
3
4
5
6
7
//求网络最大流,邻接阵形式
8
//返回最大流量,flow返回每条边的流量
9
//传入网络节点数n,容量mat,源点source,汇点sink
10
11
#define MAXN 1200
12
#define inf 1000000000
13
14
int max_flow(int n,int mat[][MAXN],int source,int sink,int flow[][MAXN]){
15
int pre[MAXN],que[MAXN],d[MAXN],p,q,t,i,j;
16
if (source==sink) return inf;
17
for (i=0;i<n;i++)
18
for (j=0;j<n;flow[i][j++]=0);
19
for (;;){
20
for (i=0;i<n;pre[i++]=0);
21
pre[t=source]=source+1,d[t]=inf;
22
for (p=q=0;p<=q&&!pre[sink];t=que[p++])
23
for (i=0;i<n;i++)
24
if (!pre[i]&&(j=mat[t][i]-flow[t][i]))
25
pre[que[q++]=i]=t+1,d[i]=d[t]<j?d[t]:j;
26
else if (!pre[i]&&(j=flow[i][t]))
27
pre[que[q++]=i]=-t-1,d[i]=d[t]<j?d[t]:j;
28
if (!pre[sink]) break;
29
for (i=sink;i!=source;)
30
if (pre[i]>0)
31
flow[pre[i]-1][i]+=d[sink],i=pre[i]-1;
32
else
33
flow[i][-pre[i]-1]-=d[sink],i=-pre[i]-1;
34
}
35
for (j=i=0;i<n;j+=flow[source][i++]);
36
return j;
37
}
38
39
40
int mat[MAXN][MAXN],flow[MAXN][MAXN];
41
int n,m;
42
void init()
43
{
44
int i,j,a,x;
45
int q[1000];
46
47
memset(mat,0,sizeof(mat));
48
49
for (i=1;i<=m;i++)
50
scanf("%d",&mat[n+i][n+m+1]);
51
52
for (i=1;i<=n;i++)
53
{
54
scanf("%d",&a);
55
for (j=0;j<a;j++)
56
{
57
scanf("%d",&q[j]);
58
mat[i][q[j]+n]=inf;
59
60
}
61
scanf("%d",&mat[0][i]);
62
}
63
for (i=1;i<=m;i++)
64
{
65
66
int pre=0;
67
for (j=1;j<=n;j++)
68
if (mat[j][i+n]>0 )
69
{
70
if (pre>0)
71
mat[j][pre]=inf;
72
pre=j;
73
}
74
}
75
}
76
77
78
79
80
81
82
int main ()
83
{
84
while (scanf("%d%d",&m,&n)==2)
85
{
86
init();
87
printf("%d\n",max_flow(n+m+2,mat,0,n+m+1,flow));
88
}
89
90
return 0;
91
92
}
93
#include <iostream>2
using namespace std;3

4

5

6

7
//求网络最大流,邻接阵形式8
//返回最大流量,flow返回每条边的流量9
//传入网络节点数n,容量mat,源点source,汇点sink10

11
#define MAXN 120012
#define inf 100000000013

14
int max_flow(int n,int mat[][MAXN],int source,int sink,int flow[][MAXN]){15
int pre[MAXN],que[MAXN],d[MAXN],p,q,t,i,j;16
if (source==sink) return inf;17
for (i=0;i<n;i++)18
for (j=0;j<n;flow[i][j++]=0);19
for (;;){20
for (i=0;i<n;pre[i++]=0);21
pre[t=source]=source+1,d[t]=inf;22
for (p=q=0;p<=q&&!pre[sink];t=que[p++])23
for (i=0;i<n;i++)24
if (!pre[i]&&(j=mat[t][i]-flow[t][i]))25
pre[que[q++]=i]=t+1,d[i]=d[t]<j?d[t]:j;26
else if (!pre[i]&&(j=flow[i][t]))27
pre[que[q++]=i]=-t-1,d[i]=d[t]<j?d[t]:j;28
if (!pre[sink]) break;29
for (i=sink;i!=source;)30
if (pre[i]>0)31
flow[pre[i]-1][i]+=d[sink],i=pre[i]-1;32
else33
flow[i][-pre[i]-1]-=d[sink],i=-pre[i]-1;34
}35
for (j=i=0;i<n;j+=flow[source][i++]);36
return j;37
}38

39

40
int mat[MAXN][MAXN],flow[MAXN][MAXN];41
int n,m;42
void init()43
{44
int i,j,a,x;45
int q[1000];46

47
memset(mat,0,sizeof(mat));48

49
for (i=1;i<=m;i++)50
scanf("%d",&mat[n+i][n+m+1]);51

52
for (i=1;i<=n;i++)53
{54
scanf("%d",&a);55
for (j=0;j<a;j++)56
{57
scanf("%d",&q[j]);58
mat[i][q[j]+n]=inf;59
60
}61
scanf("%d",&mat[0][i]);62
}63
for (i=1;i<=m;i++)64
{65
66
int pre=0;67
for (j=1;j<=n;j++)68
if (mat[j][i+n]>0 )69
{70
if (pre>0)71
mat[j][pre]=inf;72
pre=j;73
}74
} 75
}76

77

78

79

80

81

82
int main ()83
{84
while (scanf("%d%d",&m,&n)==2)85
{86
init();87
printf("%d\n",max_flow(n+m+2,mat,0,n+m+1,flow));88
}89

90
return 0;91

92
}93



浙公网安备 33010602011771号