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

题目大意:

Mirko有M个猪圈和N个客户,猪圈里有特定数量的猪,每个客户按照顺序来买猪,他们只能打开他们能打开的猪圈,然后取走一些猪(上限为每个人特定的值b),Mirko在每个客户来之后将该客户打开的猪圈内剩余的猪重新分配到该客户打开的猪圈内。

求最大取猪数量。

——————————————————————

看到n和m的数量级为网络流。

很容易能够想到一种建图方法:

1.将每个猪圈拆成N个点(代表第N个客户来的时刻每个猪圈的状态),源点连到每个猪圈第一个点,权值为该猪圈内猪的数量,之后前点连到后点权值INF。

2.客户取猪就是将他们所属的猪圈中能打开的猪圈与客户连INF边,客户向汇点连b权值的边。

3.之后将此时所有打开的猪圈的前状态与每个后状态都连INF边。

好的讲了一通是不是很简单……显然不能这么做,点太多了,O(跑不过)。

我们在拆完点之后还需要缩点:

1.如果几个结点的流量来源相同则可以合并

2.如果几个结点的流量去处相同则可以合并

3.如果两点间有INF的边,且到的点没有其他的流量来源,则可以可以合并

根据这些再画画图就能做啦!

对于新的图,我们构造的思想:

1.对于每一个用户,流入他所有能开开的猪圈的猪。

2.对于其他用户与前面的用户的猪圈有交集的,可以从他们那里“得到”猪。

参考了:https://www.cnblogs.com/sleeper-qp/archive/2012/07/23/2605253.html

//注意:此模板默认源点为1,汇点为m
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
const int INF=;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){w|=ch=='-';ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int next;
int to;
int w;
}edge[N*N*];
int head[N],cnt=-;
void add(int u,int v,int w){//u起点v终点w容量
cnt++;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
return;
}
int lev[N],cur[N];//lev层数,cur[i]为以i为起点的边的编号
bool bfs(int m){//强制1为源点,m为汇点
int dui[m],r=;//队列和右指针
for(int i=;i<=m;i++){//初始化
lev[i]=-;
cur[i]=head[i];
}
dui[]=,lev[]=;
int u,v;//u起点v终点
for(int l=;l<=r;l++){//左指针
u=dui[l];
for(int e=head[u];e!=-;e=edge[e].next){
v=edge[e].to;
if(edge[e].w>&&lev[v]==-){//1.能走 2.未分层
lev[v]=lev[u]+;
r++;
dui[r]=v;//v入队
if(v==m)return ;//分层完毕
}
}
}
return ;//无法分层
}
int dinic(int u,int flow,int m){//u当前点,flow为下面的点能够分配多大的流量,m终点
if(u==m)return flow;//终点直接全流入
int res=,delta;//res实际流量
for(int &e=cur[u];e!=-;e=edge[e].next){//'&'相当于cur[u]=e;即流满的边不会再被扫一次
int v=edge[e].to;
if(edge[e].w>&&lev[u]<lev[v]){//只能从低层往高层流
delta=dinic(v,min(edge[e].w,flow-res),m);
if(delta>){//如果增广
edge[e].w-=delta;//正向边容量减少
edge[e^].w+=delta;//反向边仍量增加(暗示退流)
res+=delta;//扩张流量增加
if(res==flow)break;//可流的都流完了,及时跳出
}
}
}
if(res!=flow)lev[u]=-;//没流完,说明以后不能从这个点流出任何流量,那就不需要这个点了
return res;
}
int num[];
int vis[];
int mp[N];
int main(){
int m=read();
int n=read();
int S=,T=n+;
memset(head,-,sizeof(head));
for(int i=;i<=m;i++)num[i]=read();
for(int i=;i<=n;i++){
int a=read();
for(int j=;j<=a;j++){
int p=read();
if(!vis[p]){
mp[i+]+=num[p];
vis[p]=i+;
}else{
add(vis[p],i+,INF);
add(i+,vis[p],);
}
}
int b=read();
add(i+,T,b);
add(T,i+,);
}
for(int i=;i<=n+;i++){
if(mp[i]){
add(S,i,mp[i]);
add(i,S,);
}
}
int ans=;
while(bfs(T))ans+=dinic(S,INF,T);
printf("%d\n",ans);
return ;
}

POJ1149:PIGS——题解的更多相关文章

  1. 题解 POJ1149 Pigs

    先翻译一下吧(题面可以在原OJ上找) Mirko在一个由M个锁着的猪舍组成的养猪场工作,Mirko无法解锁任何猪舍,因为他没有钥匙.客户纷纷来到农场.他们每个人都有一些猪舍的钥匙,并想购买一定数量的猪 ...

  2. POJ1149 PIGS 【最大流量】

    PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16555   Accepted: 7416 Description ...

  3. poj1149 PIGS 最大流(神奇的建图)

    一开始不看题解,建图出错了.后来发现是题目理解错了.  if Mirko wants, he can redistribute the remaining pigs across the unlock ...

  4. POJ1149 PIGS 【最大流 + 构图】

    题目链接:http://poj.org/problem?id=1149 PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions ...

  5. POJ1149 PIGS [最大流 建图]

    PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20662   Accepted: 9435 Description ...

  6. POJ1149 PIGS (网络流)

                                                                             PIGS Time Limit: 1000MS   M ...

  7. POJ1149 PIGS

    想了好久啊...(#-.-) 开始想到m*n个点的构图,明显超时,于是考虑压缩节点个数 我们发现每个猪圈最后被有且只有一个人调整,于是想到对于一个人,连接他能调整的每个猪圈的上一个控制人.(不懂可以开 ...

  8. POJ1149 PIGS(最大流)

    题意:       有一个人,他有m个猪圈,每个猪圈里面有一定数量的猪,但是每个猪圈的门都是锁着的,他自己没有钥匙,只有顾客有钥匙,一天依次来了n个顾客,(记住是依次来的)他们每个人都有一些钥匙,和他 ...

  9. poj图论解题报告索引

    最短路径: poj1125 - Stockbroker Grapevine(多源最短路径,floyd) poj1502 - MPI Maelstrom(单源最短路径,dijkstra,bellman- ...

随机推荐

  1. What is the "internal" interface and port for on Openvswitch?

    转:https://ask.openstack.org/en/question/4276/what-is-the-internal-interface-and-port-for-on-openvswi ...

  2. jQuery tableExport导出 excel

    上篇写的是jQuery 导出word,就试试导出excel.看见网上写的很乱,我这就把我写的整理下来,有部分来自网上capy 1.   js文件的引用 <script type="te ...

  3. Bing wallpaper api

    list: http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-cn idx:-1为明天,1为 ...

  4. hdu1050Moving Tables(贪心)

    Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  5. 韦大仙--Katalon---一款好用的selenium自动化测试插件

    selenium框架是目前使用较广泛的开源自动化框架,一款好的.基于界面的录制工具对于初学者来说可以快速入门:对于老手来说可以提高开发自动化脚本的效率.我们知道Selenium IDE是一款使用较多的 ...

  6. 谜题 (Puzzle,ACM/ICPC World Finals 1993,UVa227)

    题目描述:算法竞赛入门经典习题3-5 题目思路:模拟题 #include <stdio.h> #include <string.h> #define maxn 55 char ...

  7. 火狐metamask账号

    火狐metamask lock trophy pyramid sunny aim inmate body sense sing castle cinnamon cram

  8. Python字符串中的r前缀

    在Python中,如果字符串的前面有r/R前缀,那么,就会禁用转义符\的功能: >>>path = r'C:\new\text.dat' >>>pah 'C:\\n ...

  9. default & delete

    一.使用“=default” 1. 显式生成拷贝控制成员的合成版本 class A { public: A() = default; A(const A &) = default; A& ...

  10. eg_1

    1. 编写一个程序,输出一个字符串中的大写英文字母个数,小写英文字母个数以及非英文字母个数. 第一种方法: public class Test { public static void main(St ...