您的位置:首页 > 其它

【POJ 1149】 Pigs 最大流

2011-04-05 16:11 405 查看
大意是这样的:

· 有 M 个猪圈(M ≤ 1000),每个猪圈里初始时有若干头猪。
· 一开始所有猪圈都是关闭的。
· 依次来了 N 个顾客(N ≤ 100),每个顾客分别会打开指定的几个猪圈,从中买若干头猪。
· 每个顾客分别都有他能够买的数量的上限。
· 每个顾客走后,他打开的那些猪圈中的猪,都可以被任意地调换到其它开着的猪圈里,然后所有猪圈重新关上。
问总共最多能卖出多少头猪。
看过之后,参考了网上的思路才明白的。
只能感叹一句:最大流要在图上做,可是,图在哪儿啊,图在哪儿啊。。有时候建立出来图了,发现自己建立的图 思路 : 如果一个顾客打开了一个没有被打开过的猪舍,则从源点发出一条容量为该猪舍中猪的头数的边。如果一个顾客打开了一个已经打开过的猪舍,则从上一个打开该猪舍的顾客向该顾客添加一条容量为无穷大的边。然后,每个顾客都有一条流向汇点的边,容量为该顾客要买的猪要数量。 求出最大流即可。 用的以前写的SAP邻接表模板,0MS


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#define CLR(arr, val) memset(arr, val, sizeof(arr))
using namespace std;
const int MAX=110,MAXE=1000*2,INF=100000000;
inline int rev(int n)
{
return n+1 - 2* (n&1);
}
struct Graph
{
public:
Graph():top(0)
{
CLR(head,-1);
CLR(next,-1);
}
void Add(int u,int v,int c)
{
cap[top]=c;
num[top]=v;
next[top]=head[u];
head[u]=top;
++top;
cap[top]=0;
num[top]=u;
next[top]=head[v];
head[v]=top;
++top;
}
int head[MAX];
int next[MAXE];
int num[MAXE];
int cap[MAXE];
int flow[MAXE];
private:
int top;
};
class SapMaxFlow
{
public:
int GetMaxFlow(int s,int t,int v)
{
init(t, v);
int total_flow = 0, cur = s;
CLR(low,0);
while(h[s] < v)
{
low[s] = INF;
int i;
for(i = g1.head[cur]; i != -1; i = g1.next[i])
{
int u = g1.num[i], c = g1.cap[i], f = g1.flow[i];
if (c - f > 0 && h[cur] == h[u] + 1)
{
low[u] = min(low[cur],c - f);
pre[u] = cur;
pre_edge[u] = i;
cur = u;
if( cur == t)
{
total_flow += low[t];
while(cur != s)
{
g1.flow[pre_edge[cur]] += low[t];
g1.flow[rev(pre_edge[cur])] -= low[t];
cur=pre[cur];

}
CLR(low,0);
}
break;
}
}
if(i==-1)
{
int minh=INF;
for(int i=g1.head[cur];i!=-1;i=g1.next[i])
if(g1.cap[i] - g1.flow[i] > 0 && h[g1.num[i]]+1<minh) minh = h[g1.num[i]]+1;
h[cur] = minh;
cur = s;
}
}
return total_flow;
}
void Add(int u,int v,int c)
{
g1.Add(u,v,c);
g2.Add(v,u,c);
}
Graph g1,g2;
private:

int h[MAX],q[MAX],low[MAX],pre[MAX],pre_edge[MAX];
void init(int t,int v)
{
int head = 0,tail = 0;
q[++tail]=t;
h[t]=0;
while(head < tail)
{
int cur=q[++head];
for(int i=g2.head[cur];i!=-1;i=g2.next[i])
{
int u=g2.num[i],c=g2.cap[i];
if(!h[u] && c>0)
{
h[u]=h[cur]+1;
q[++tail]=u;
}
}
}
}
};
int pigs[1100];
int pigcus[1100];
SapMaxFlow g;
int main()
{
//freopen("in.txt","r",stdin);
memset(pigcus,-1,sizeof(pigcus));
int M,N,num,tt,s,t,v;
scanf("%d%d",&M,&N);
s = N;t = N+1; v= N+2;
for(int i=1;i<=M;i++)
scanf("%d",&pigs[i]);
for(int i=0;i!=N;i++)
{
scanf("%d",&num);
for(int j=0;j!=num;j++)
{
scanf("%d",&tt);
if(pigcus[tt]!=-1)
g.Add(pigcus[tt],i,INF);
else g.Add(s,i,pigs[tt]);
pigcus[tt] = i;
}
scanf("%d",&tt);
g.Add(i,t,tt);
}
cout<<g.GetMaxFlow(s,t,v);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: