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. JavaSE打开windows文件

    第一个参数表示用什么程序打开,第二个参数表示文件的路径 例一: //用记事本打开d:/test.txt文件 Process p = java.lang.Runtime.getRuntime().exe ...

  2. /proc/meminfo详解

    cat /proc/meminfo   读出的内核信息进行解释, 下篇文章会简单对读出该信息的代码进行简单的分析. MemTotal:       507480 kB MemFree:         ...

  3. 网易七鱼 Android 高性能日志写入方案

    本文来自网易云社区 作者:网易七鱼 Android 开发团队 前言 网易七鱼作为一款企业级智能客服系统,对于系统稳定性要求很高,不过难保用户在使用中不会出现问题,而 Android SDK 安装在用户 ...

  4. git 操作几个命令

     git clone ssh://lijianfeng@192.168.1.246:29418/GMGameSDK压栈:git stash查状态:git status切换到要修改的提交:git reb ...

  5. Qt-QML-给我的导航条写一个动画-State-Transition

    上篇中,我已经写出一个导航条的,虽然太丑了,不过功能是有了,这次我将要给我的导航条加一个动画,先看下演示效果 这次我是用的是一个状态动画,大致原理就是写出一个空间的几个状态,完了再加一个过度动画,这里 ...

  6. Selenium(Python)调用pywin32上传图片

    import unittestfrom time import sleep import osfrom selenium import webdriverimport win32apiimport w ...

  7. Spring全局变量

    压测spring框架的webservice接口,大并发量下响应值与预期值不一致 经查,开发在类中使用全局变量导致: springmvc核心控制器DispatcherServlet 默认为每个contr ...

  8. Oracle-数据库增删改查基本操作

    一.创建数据表 1).创建不存在的新表: create table tname(  Data_Name Date_Type [default][默认值]  );2).创建已存在表的副本 create ...

  9. CSS让内部元素以相反的顺序显示

    代码如下: <div id="main" style=" flex-direction: row-reverse;-webkit-flex-direction: r ...

  10. python3对接聊天机器人API

    详情见http://api.qingyunke.com/智能机器人API接口说明支持功能:天气.翻译.藏头诗.笑话.歌词.计算.域名信息/备案/收录查询.IP查询.手机号码归属.人工智能聊天接口地址: ...