专题链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68128#overview

网络流基础知识:http://www.cnblogs.com/yaoyueduzhen/p/5020722.html

本专题考察网络流问题, 包含最大流和最小费用最大流,请使用高效模板。

 

A.  poj3436    ACM Computer Factory

分析:这个是一个网络流,对流过每个点的流量有限制,这样就需要拆点,把每个结点拆成两个,一个入点,一个出点,并从入点到出点连接一条边流量为点的的流向限制,把所有接入该点的边接入它的入点,从该点流出的边从出点流出。

建图方法,每个机器是一个点,把源与所有没有必须元件的点连接,所有完整元件的点与汇连接,若一台机器的输出能符合另一台机器的输入条件则连一条边。把每个机器拆点,其内部边流量为其生产速度。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 
  6 using namespace std;
  7 const int MAXN=120;
  8 const int MAXM=120*120;
  9 const int INF=0x3f3f3f3f;
 10 int p,n;
 11 int q[MAXN];
 12 int in[MAXN][MAXN],out[MAXN][MAXN];
 13 
 14 struct Edge 
 15 {
 16     int to, next, cap, flow;
 17 }edge[MAXM];
 18 int tol;
 19 int head[MAXN];
 20 void init() 
 21 {
 22     tol = 2;
 23     memset(head, -1, sizeof(head));
 24 }
 25 void addedge(int u, int v, int w, int rw=0) 
 26 {
 27     edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
 28     edge[tol].next = head[u]; head[u] = tol++;
 29     edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;
 30     edge[tol].next = head[v]; head[v] = tol++;
 31 }
 32 int Q[MAXN];
 33 int dep[MAXN], cur[MAXN], sta[MAXN];
 34 bool bfs(int s, int t, int n) 
 35 {
 36     int front = 0, tail = 0;
 37     memset(dep, -1, sizeof(dep));
 38     dep[s] = 0;
 39     Q[tail++] = s;
 40     while(front < tail)
 41     {
 42         int u = Q[front++];
 43         for(int i = head[u]; i != -1; i = edge[i].next) 
 44         {
 45             int v = edge[i].to;
 46             if(edge[i].cap > edge[i].flow && dep[v] == -1)                 
 47             {
 48                 dep[v] = dep[u] + 1;
 49                 if(v == t) return true;
 50                 Q[tail++] = v;
 51             }
 52         }
 53     }
 54     return false;
 55 }
 56 
 57 int dinic(int s, int t, int n) 
 58 {
 59     int maxflow = 0;
 60     while(bfs(s, t, n)) 
 61     {
 62         for(int i = 0; i < n; i++) cur[i] = head[i];
 63         int u = s, tail = 0;
 64         while(cur[s] != -1)
 65         {
 66             if(u == t) 
 67             {
 68                 int tp = INF;
 69                 for(int i = tail-1; i >= 0; i--)
 70                     tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow);
 71                 maxflow+=tp;
 72                 for(int i = tail-1; i >= 0; i--) 
 73                 {
 74                     edge[sta[i]].flow+=tp;
 75                     edge[sta[i]^1].flow-=tp;
 76                     if(edge[sta[i]].cap-edge[sta[i]].flow==0)
 77                         tail = i;
 78                 }
 79                 u = edge[sta[tail]^1].to;
 80             }
 81             else 
 82                 if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) 
 83                 {
 84                     sta[tail++] = cur[u];
 85                     u = edge[cur[u]].to;
 86                 }
 87                 else 
 88                 {
 89                     while(u != s && cur[u] == -1)
 90                         u = edge[sta[--tail]^1].to;
 91                     cur[u] = edge[cur[u]].next;
 92                 }
 93         }
 94     }
 95     return maxflow;
 96 }
 97 
 98 int main()
 99 {
100     scanf("%d%d",&p,&n);
101     init();
102     for(int i=1;i<=n;++i)
103     {
104         scanf("%d",&q[i]);
105         for(int j=1;j<=p;++j)
106             scanf("%d",&in[i][j]);
107         for(int j=1;j<=p;++j)
108             scanf("%d",&out[i][j]);
109     }
110     for(int i=1;i<=n;++i)
111         addedge(i,n+i,q[i]);
112     for(int i=1;i<=n;++i)
113         for(int j=1;j<=n;++j)
114             if(i!=j)
115             {
116                 bool flag=true;
117                 for(int k=1;k<=p;++k)
118                 {
119                     if(out[i][k]==0&&in[j][k]==1)
120                     {
121                         flag=false;
122                         break;
123                     }
124                     if(out[i][k]==1&&in[j][k]==0)
125                     {
126                         flag=false;
127                         break;
128                     }
129                 }
130                 if(flag)
131                     addedge(i+n,j,min(q[i],q[j]));
132             }
133     for(int i=1;i<=n;++i)
134     {
135         bool f=true;
136         for(int j=1;j<=p;++j)
137         {
138             if(in[i][j]==1)
139             {
140                 f=false;
141                 break;
142             }
143         }
144         if(f)    addedge(0,i,q[i]);
145     }
146     for(int i=1;i<=n;++i)
147     {
148         bool f=true;
149         for(int j=1;j<=p;++j)
150         {
151             if(out[i][j]==0)
152             {
153                 f=false;
154                 break;
155             }
156         }
157         if(f) 
158             addedge(i+n,2*n+1,q[i]);
159     }
160     int res=dinic(0,2*n+1,2*n+2);
161     int count=0;
162     for(int i=1;i<=n;++i)
163         for(int j=head[i+n];j!=-1;j=edge[j].next)
164             if(edge[j].to!=2*n+1&&edge[j].flow>0)
165                 count++;
166     cout<<res<<" "<<count<<endl;
167     for(int i=1;i<=n;++i)
168         for(int j=head[i+n];j!=-1;j=edge[j].next)
169             if(edge[j].to!=2*n+1&&edge[j].flow>0)
170                 cout<<i<<" "<<edge[j].to<<" "<<edge[j].flow<<endl;
171     return 0;
172 }
View Code

相关文章: