POJ 1149-PIGS(Ford-Fulkerson 標號法求網路最大流)
PIGS
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20029 | Accepted: 9178 |
Description
Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because he doesn't have the keys. Customers come to the farm one after another. Each of them has keys to some pig-houses and wants to buy a certain number of
pigs.
All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.
More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
An unlimited number of pigs can be placed in every pig-house.
Write a program that will find the maximum number of pigs that he can sell on that day.
All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.
More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
An unlimited number of pigs can be placed in every pig-house.
Write a program that will find the maximum number of pigs that he can sell on that day.
Input
The first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M and customers are numbered from 1 to N.
The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.
The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):
A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.
The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.
The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):
A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.
Output
The first and only line of the output should contain the number of sold pigs.
Sample Input
3 3 3 1 10 2 1 2 2 2 1 3 3 1 2 6
Sample Output
7
Source
題目意思:
有M個豬圈,N個顧客,給出每個豬圈中豬的數目。
每個顧客有A把鑰匙,對應A個豬圈的編號,每個顧客會買B頭豬。
Mark木有豬圈的鑰匙,每個顧客來的時候把他們有鑰匙的豬圈全部開啟;而且Mark可以重新分配被開啟的豬圈裡面的豬。
顧客離開後,豬圈再次被鎖上。
求Mark能賣出的豬的最大值。
解題思路:
Ford-Fulkerson 標號法求網路最大流。
除了顧客的N個頂點外,自己增加源點和匯點這兩個點。
每個顧客購買的數目是連線到匯點上的容量;
源點與每個豬圈的第一個顧客連邊,邊的容量是開始時豬圈中豬的數目;
若源點與某個結點之間有重邊,將權合併(如上圖中Vs~V1,4就是合併了1和3);
若顧客j緊跟i後面開啟豬圈,那麼<i,j>容量為正無窮(因為此時可以隨意調整豬圈中的豬的數量)。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <iomanip>
#include <algorithm>
#define maxn 1010
#define INF 0xfffffff
using namespace std;
struct ArcType
{
int c,f;//容量、流量
};
ArcType edge[maxn][maxn];
int n,m;//頂點數、弧數
int s,t;
int flag[maxn];//頂點狀態:-1——未標號;0——已標號未檢查;1——已標號已檢查
int prev[maxn];//標號的第一個分量:指明標號從哪個頂點而來,以便找出可改進量
int alpha[maxn];//標號的第二個分量:可改進量α
int que[maxn];//相當於BFS中的佇列
int v;//佇列頭元素
int qs,qe;//隊首隊尾的位置
int i,j;
void ford()//標號法求網路最大流
{
int flow[maxn][maxn];//節點之間的流量Fij
int prev[maxn];//可改進路徑上前一個節點的標號,相當於標號的第一個分量
int minflow[maxn];//每個頂點的可改進量α,相當於標號的第二個分量
int que[maxn];
int qs,qe;//佇列首尾位置座標
int v,p;//當前頂點、儲存Cij-Fij
for(i=0; i<maxn; ++i)
for(j=0; j<maxn; ++j)
flow[i][j]=0;
minflow[0]=INF;//源點標號的第二分量為無窮大
while(1)//標號法
{
for(i=0; i<maxn; ++i)//每次標號前,每個頂點重新回到未標號狀態
prev[i]=-2;
prev[0]=-1;
qs=0;
que[qs]=0;//源點入隊
qe=1;
while(qs<qe&&prev[t]==-2)
{
v=que[qs];//取佇列頭節點
++qs;
for(i=0; i<t+1; ++i)//prev[i]==-2表示頂點i未標號
if(prev[i]==-2&&(p=edge[v][i].c-flow[v][i]))//edge[v][i].c-flow[v][i]!=0能保證i是v鄰接頂點且能進行標號
{
prev[i]=v;
que[qe]=i;
++qe;
minflow[i]=(minflow[v]<p)?minflow[v]:p;
}
}
if(prev[t]==-2) break;//匯點t無標號,標號法結束
for(i=prev[t],j=t; i!=-1; j=i,i=prev[i])//調整過程
{
flow[i][j]+=minflow[t];
flow[j][i]=-flow[i][j];
}
}
for(i=0,p=0; i<t; ++i)//統計進入匯點的流量即最大流的流量
p+=flow[i][t];
cout<<p<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>m>>n;//頂點個數、弧數
s=0,t=n+1;//源點和匯點
int pig[maxn],last[maxn];//每個豬圈中豬的數量、每個豬圈前一個顧客的序號
memset(last,0,sizeof(last));
for(i=1; i<=m; ++i)
cin>>pig[i];//輸入每個豬圈中豬的數量
for(i=1; i<=n; ++i)
{
int num;
cin>>num;//擁有的豬圈鑰匙數量
for(j=0; j<num; ++j)
{
int k;
cin>>k;//鑰匙編號
if(last[k]==0)
edge[s][i].c+=pig[k];
else edge[last[k]][i].c=INF;
last[k]=i;
}
cin>>edge[i][t].c;
edge[i][t].f=0;
}
n+=2;//加上源點和匯點
ford();
return 0;
}
/*
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
*/
相關文章
- Ford-Fulkerson 標號法求網路最大流
- poj1087 網路最大流
- POJ1273 Drainage Ditches【網路流 最大流】AI
- poj 3436 最大流的增廣路演算法演算法
- 網路流最大流
- EK求最大流
- 淺談網路最大流
- hdu 4292 網路最大流
- 【模板】網路流最大流
- 網路最大流演算法演算法
- 網路流(最大流,最小割)
- Dinic/ISAP求最大流
- 網路中最小費用最大流
- 網路最大流 Dinic演算法演算法
- POJ 3308 Paratroopers 最小割、最大流OOP
- 網路---無法訪問目標主機和請求超時的區別
- 【網路流】有源匯上下界最大流
- POJ 2195 Going Home 最小費用最大流Go
- POJ 2195 Going Home (最小費用最大流)Go
- 最嚴網路資訊稽核標準!11種內容涉嫌違法,你“中招”了嗎?
- 【計算機網路常見面試題】利用IP地址和子網掩碼求網路號和主機號計算機網路面試題
- 多個網路請求中GCD訊號量的使用GC
- POJ-2299 Ultra-QuickSort-分治法排序求交換速度UI排序
- poj3080-kmp+列舉子串 求最長公共子串KMP
- poj 2774 求兩字串的最長公共子串 字尾陣列字串陣列
- Android網路請求(終) 網路請求框架RetrofitAndroid框架
- Android網路請求(3) 網路請求框架OkHttpAndroid框架HTTP
- 網路流最大流、最小割學習筆記筆記
- Android網路請求(4) 網路請求框架VolleyAndroid框架
- POJ 3693 Maximum repetition substring(字尾陣列求最長重複子串)陣列
- POJ 3294 Life Forms(字尾陣列求k個串的最長子串)ORM陣列
- volley建立標準的網路請求(Making a Standard Request)
- 網路請求了
- [網路流24題] 魔術球問題 (最大流)
- POJ 3469-Dual Core CPU(Dinic 最大流/最小割演算法)演算法
- 美國網際網路大流量網站和社交網路一天資料分佈圖網站
- SQLServer最大流水號的解決方法SQLServer
- POJ 1743 Musical Theme (字尾陣列,求最長不重疊重複子串)陣列