nicholas

nicholas
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>
 2using namespace std;
 3
 4
 5
 6
 7//求网络最大流,邻接阵形式
 8//返回最大流量,flow返回每条边的流量
 9//传入网络节点数n,容量mat,源点source,汇点sink
10
11#define MAXN 1200
12#define inf 1000000000
13
14int 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
40int mat[MAXN][MAXN],flow[MAXN][MAXN];
41int n,m;
42void 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
82int 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

posted on 2007-09-07 21:14  zy_nic  阅读(972)  评论(0)    收藏  举报