POJ 3436 ACM Computer Factory(最大流+路径输出)

http://poj.org/problem?id=3436

题意:

每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了。计算机的生产过程通过N台不同的机器来完成,每台机器用它的性能(每小时组装多少台电脑)、输入/输出规格来描述。

输入规格描述了机器在组装计算机时哪些部件必须准备好了。输入规格是由P个整数组成,每个整数代表一个部件,这些整数取值为0、1或2,其中0表示该部件不应该已经准备好了,1表示该部件必须已经准备好了,2表示该部件是否已经准备好了无关紧要。

输出规格描述了该机器组装的结果。输出规格也是由P个整数组成,每个整数取值 为0或1,其中0代表该部件没有生产好,1代表该部件生产好了。

输出每单位时间内的最大产量和连接数量和路径。

思路:
因为每台机器都有一个产量,所以这里拆点,容量为机器的产量。

对每台机器进行检验,如果它的要求中不包含1,那么它就和源点相连,说明这台机器是可以最先开始组装电脑的,如果它的输出中全是1,说明这台机器已经把电脑组装好了,和汇点相连。

然后机器之间两两判断,是否可以相连。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,int> pll;
 15 const int INF = 0x3f3f3f3f;
 16 const int maxn = 200 + 5;
 17 
 18 struct Edge
 19 {
 20     int from,to,cap,flow;
 21     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 22 };
 23 
 24 struct Dinic
 25 {
 26     int n,m,s,t;
 27     vector<Edge> edges;
 28     vector<int> G[maxn];
 29     bool vis[maxn];
 30     int cur[maxn];
 31     int d[maxn];
 32 
 33     void init(int n)
 34     {
 35         this->n=n;
 36         for(int i=0;i<n;++i) G[i].clear();
 37         edges.clear();
 38     }
 39 
 40     void AddEdge(int from,int to,int cap)
 41     {
 42         edges.push_back( Edge(from,to,cap,0) );
 43         edges.push_back( Edge(to,from,0,0) );
 44         m=edges.size();
 45         G[from].push_back(m-2);
 46         G[to].push_back(m-1);
 47     }
 48 
 49     bool BFS()
 50     {
 51         queue<int> Q;
 52         memset(vis,0,sizeof(vis));
 53         vis[s]=true;
 54         d[s]=0;
 55         Q.push(s);
 56         while(!Q.empty())
 57         {
 58             int x=Q.front(); Q.pop();
 59             for(int i=0;i<G[x].size();++i)
 60             {
 61                 Edge& e=edges[G[x][i]];
 62                 if(!vis[e.to] && e.cap>e.flow)
 63                 {
 64                     vis[e.to]=true;
 65                     d[e.to]=d[x]+1;
 66                     Q.push(e.to);
 67                 }
 68             }
 69         }
 70         return vis[t];
 71     }
 72 
 73     int DFS(int x,int a)
 74     {
 75         if(x==t || a==0) return a;
 76         int flow=0, f;
 77         for(int &i=cur[x];i<G[x].size();++i)
 78         {
 79             Edge &e=edges[G[x][i]];
 80             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 81             {
 82                 e.flow +=f;
 83                 edges[G[x][i]^1].flow -=f;
 84                 flow +=f;
 85                 a -=f;
 86                 if(a==0) break;
 87             }
 88         }
 89         return flow;
 90     }
 91 
 92     int Maxflow(int s,int t)
 93     {
 94         this->s=s; this->t=t;
 95         int flow=0;
 96         while(BFS())
 97         {
 98             memset(cur,0,sizeof(cur));
 99             flow +=DFS(s,INF);
100         }
101         return flow;
102     }
103 }DC;
104 
105 int p,n;
106 int w[maxn];
107 int s[maxn][maxn];
108 int d[maxn][maxn];
109 
110 bool isStart(int x)
111 {
112     for(int i=1;i<=p;i++)
113         if(s[x][i]==1)  return false;
114     return true;
115 }
116 
117 bool isEnd(int x)
118 {
119     for(int i=1;i<=p;i++)
120     {
121         if(d[x][i]==0)  return false;
122     }
123     return true;
124 }
125 
126 bool connect(int x, int y)
127 {
128     for(int i=1;i<=p;i++)
129     {
130         if((s[y][i]==1 && d[x][i]==0) ||(s[y][i]==0 && d[x][i]==1))   return false;
131     }
132     return true;
133 }
134 
135 int main()
136 {
137     //freopen("in.txt","r",stdin);
138     while(~scanf("%d%d",&p,&n))
139     {
140         int src=0, dst=2*n+1;
141         DC.init(dst+1);
142 
143         for(int i=1;i<=n;i++)
144         {
145             scanf("%d",&w[i]);
146 
147             for(int j=1;j<=p;j++)
148                 scanf("%d",&s[i][j]);
149             for(int j=1;j<=p;j++)
150                 scanf("%d",&d[i][j]);
151 
152             if(isStart(i)) DC.AddEdge(src,i,INF);
153             if(isEnd(i))  DC.AddEdge(i+n,dst,INF);
154         }
155 
156         for(int i=1;i<=n;i++)  DC.AddEdge(i,i+n,w[i]);
157 
158         for(int i=1;i<=n;i++)
159         {
160             for(int j=1;j<=n;j++)
161             {
162                 if(i==j)  continue;
163                 if(connect(i,j))   DC.AddEdge(i+n,j,INF);
164             }
165         }
166 
167         int ans=DC.Maxflow(src,dst);
168 
169         int cnt=0;
170         for(int i=0;i<DC.edges.size();i++)
171         {
172             Edge& e=DC.edges[i];
173             if(e.from==src || e.from==dst || e.to==src || e.to==dst)  continue;
174             if((e.from+n)==e.to||(e.from-n)==e.to)  continue;
175             if(e.flow<0)  cnt++;
176         }
177         printf("%d %d
",ans,cnt);
178 
179         for(int i=0;i<DC.edges.size();i++)
180         {
181             Edge& e=DC.edges[i];
182             if(e.from==src || e.from==dst || e.to==src || e.to==dst)  continue;
183             if((e.from+n)==e.to||(e.from-n)==e.to)  continue;
184             if(e.flow<0)
185                 printf("%d %d %d
",e.to-n,e.from,-e.flow);
186         }
187     }
188     return 0;
189 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7220223.html