P1517 飘飘乎居士的乌龟
时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
飘飘乎居士养了乌龟。当然,这些乌龟是用来出售赚取利润的。
描述
飘飘乎居士的乌龟被安置在了m个窝中。现在,飘飘乎居士已经接到了n个人的定购通知,他们会按顺序在来挑选乌龟,其中,第i个人会在pi个窝中挑选乌龟, 但最多只想买xi只乌龟。另外,在第i个人购买完乌龟以后,飘飘乎居士会将指定的qi个窝中的龟进行调整,他可以任意调换指定的qi个窝中乌龟数量。飘飘 乎希望知道,在n个人购买完乌龟后,他最多可以出售多少只乌龟?
输入格式
输入格式:第一行,两个正整数n、m。
接下来一行m个整数(可能为0),第i个整数表示第i个窝中乌龟的数量。
接下来输入分为n组,每组3行输入,第i组表示第i个人的信息:
第一行一个整数xi,表示第i个人最多购买的乌龟数量
第二行一个整数pi以及pi整数,表示该顾客会在pi个指定的窝中挑选乌龟
第三行一个整数qi(qi可能为0)以及跟着的qi个正整数,表示在第i个人购买完乌龟后,飘飘乎居士会调整这qi个窝中乌龟的数量。
接下来一行m个整数(可能为0),第i个整数表示第i个窝中乌龟的数量。
接下来输入分为n组,每组3行输入,第i组表示第i个人的信息:
第一行一个整数xi,表示第i个人最多购买的乌龟数量
第二行一个整数pi以及pi整数,表示该顾客会在pi个指定的窝中挑选乌龟
第三行一个整数qi(qi可能为0)以及跟着的qi个正整数,表示在第i个人购买完乌龟后,飘飘乎居士会调整这qi个窝中乌龟的数量。
输出格式
输出格式:一行,表示飘飘乎居士最多出售乌龟的数量。
测试样例1
输入
输入样例1:
2 4
2 2 5 0
3
1 3
2 1 4
10
2 4 3
0
输入样例2:
2 4
1 2 3 3
3
2 1 4
2 4 3
4
1 3
4 1 2 3 4
输出
输出样例1:
7
输出样例2:
7
备注
Hint:样例一解释:飘飘乎居士4个窝,初始时,第一个窝里有2只乌龟,第二个窝里有2只乌龟,第三个窝里有5只乌龟;第四窝里没有乌龟,共有2位顾客来购买乌龟。
在 第一位顾客到来时,他想在3号窝中挑选乌龟,最多只想买3只乌龟。飘飘乎居士将3号窝中的乌龟出售。出售以后,3号窝剩下2只乌龟,飘飘乎居士可以调整 1、4号窝中乌龟的数量,将1号窝中的2只乌龟转入4号窝中,这样,1号窝没有乌龟,3号窝2只乌龟,4号窝有2只乌龟。
在第二个顾客来时,他想要在3 4号窝中挑选最多10只乌龟,飘飘乎居士将从1号窝调整到4号窝中的2只乌龟以及3号窝剩下的2只乌龟卖出。共卖出7只乌龟,也就是最后的答案。
数据范围:0<n、m<=10
每个窝初始时乌龟的数量以及每位顾客购买乌龟的数量<=100000
0<=Pi、qi<=n
数据保证输入的正确性。
【思路】
最大流。
构图:
1 对于每个龟窝建立n个结点,建立s t点。
2 连边:
(s,ui,twi) 表示龟的数量
(ui,tmp,INF),(tmp,t,xi) tmp为中转结点,限制pi个点的总流量
(qj,qj+1,INF) 表示乌龟的调换
(ui,ui+1,INF)
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<vector> 5 #define FOR(a,b,c) for(int a=(b);a<(c);a++) 6 using namespace std; 7 8 const int maxn = 500+10; 9 const int INF = 1e9; 10 11 struct Edge{ 12 int u,v,cap,flow; 13 }; 14 struct Dinic { 15 int n,m,s,t; 16 bool vis[maxn]; 17 int d[maxn],cur[maxn]; 18 vector<int> G[maxn]; 19 vector<Edge> es; 20 21 void init(int n) { 22 this->n=n; 23 es.clear(); 24 for(int i=0;i<n;i++) G[i].clear(); 25 } 26 void AddEdge(int u,int v,int cap) { 27 es.push_back((Edge){u,v,cap,0}); 28 es.push_back((Edge){v,u,0,0}); 29 m=es.size(); 30 G[u].push_back(m-2); 31 G[v].push_back(m-1); 32 } 33 34 bool BFS() { 35 queue<int> q; 36 memset(vis,0,sizeof(vis)); 37 q.push(s); vis[s]=1; d[s]=0; 38 while(!q.empty()) { 39 int u=q.front(); q.pop(); 40 for(int i=0;i<G[u].size();i++) { 41 Edge& e=es[G[u][i]]; 42 int v=e.v; 43 if(!vis[v] && e.cap>e.flow) { 44 vis[v]=1; 45 d[v]=d[u]+1; 46 q.push(v); 47 } 48 } 49 } 50 return vis[t]; 51 } 52 int DFS(int u,int a) { 53 if(u==t || a==0) return a; 54 int flow=0,f; 55 for(int& i=cur[u];i<G[u].size();i++){ 56 Edge& e=es[G[u][i]]; 57 int v=e.v; 58 if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) { 59 e.flow+=f; 60 es[G[u][i]^1].flow-=f; 61 flow+=f,a-=f; 62 if(!a) break; 63 } 64 } 65 return flow; 66 } 67 int Maxflow(int s,int t) { 68 this->s=s , this->t=t; 69 int flow=0; 70 while(BFS()) { 71 memset(cur,0,sizeof(cur)); 72 flow+=DFS(s,INF); 73 } 74 return flow; 75 } 76 } dc; 77 78 int n,m; 79 int q[maxn]; 80 81 int main() { 82 scanf("%d%d",&n,&m); m++; 83 dc.init(n*m+2); 84 int s=n*m,t=s+1,x; 85 FOR(i,0,m-1) { 86 scanf("%d",&x); 87 dc.AddEdge(s,i,x); 88 } 89 int a,b,limit; 90 FOR(i,0,n) { 91 scanf("%d%d",&limit,&a); 92 int tmp=i*m+m-1; //中转结点 93 dc.AddEdge(tmp,t,limit); 94 FOR(j,0,a) { 95 scanf("%d",&b); b--; 96 dc.AddEdge(i*m+b,tmp,INF); 97 } 98 scanf("%d",&a); 99 FOR(j,0,a) scanf("%d",&q[j]),q[j]--; 100 if(i<n-1) FOR(j,0,a-1) { 101 dc.AddEdge(i*m+q[j],(i+1)*m+q[j+1],INF); 102 dc.AddEdge(i*m+q[j+1],(i+1)*m+q[j],INF); 103 } 104 } 105 FOR(i,0,n-1) FOR(j,0,m-1) 106 dc.AddEdge(i*m+j,(i+1)*m+j,INF); 107 int flow=dc.Maxflow(s,t); 108 printf("%d\n",flow); 109 return 0; 110 }