POJ 1149 PIGS Solution
来源:互联网 发布:全景优化 编辑:程序博客网 时间:2024/06/15 19:08
比较垃圾所以刷的尽是些水题
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.
Solution
首先我们想到把猪圈复制n遍然后建边。
最后在猪圈和人之间建边。
然而点太多Dinic跑不出来。
我们可以考虑缩掉一些点。
1)以后不向人连边的点就没必要复制了。
2)如果对于边c(u,v)=INF,那就可以把u,v给缩了
3)如果有些点他们的流量来源完全相同则可以缩掉。
4)如果有些点他们的流量流出完全相同则可以缩掉。
这样一通缩点以后我们可以惊奇地发现猪圈没了,只有人之间有边。
并且连边的规则是这样的:
对于一个人如果与他相连的猪圈没有被其他人连过则该人与src连一条容量为猪圈中猪的数量的边
不然就和上个连这个猪圈的人连一条容量为INF的边。
然后就可以过掉了。
Edelweiss神牛有一句很有意思的总结:
在面对网络流问题时,如果一时想不出很好的构图方法,不如先构造一个最直观,或者说最“硬来”的模型,然后再用合并节点和边的方式来简化这个模型。经过简化以后,好的构图思路就会涌现出来了。这是解决网络流问题的一个好方法。
[源代码]
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;const int M=2e4+5;const int INF=1<<30;struct Edge{int to,cap,nxt;}edge[M<<1];int head[M],work[M],tot_edge,A[M],sink,src,last[M],dis[M],n,m;inline void add_edge(int from,int to,int c){ edge[tot_edge]=(Edge){to,c,head[from]}; head[from]=tot_edge++; edge[tot_edge]=(Edge){from,0,head[to]}; head[to]=tot_edge++;}bool mark[M];inline int dfs(int v,int f){ if(v==sink)return f; mark[v]=1; for(int &i=work[v];~i;i=edge[i].nxt){ int to=edge[i].to; if(!mark[to]&&dis[to]==dis[v]+1&&edge[i].cap){ int d=dfs(to,min(f,edge[i].cap)); if(d){ edge[i].cap-=d; edge[i^1].cap+=d; return d; } } } return 0;}queue<int>que;inline bool bfs(){ for(int i=1;i<=n;++i) dis[i]=-1; que.push(src); dis[src]=0; for(;!que.empty();){ int v=que.front();que.pop(); for(int i=head[v];~i;i=edge[i].nxt){ int to=edge[i].to; if(dis[to]==-1&&edge[i].cap){ dis[to]=dis[v]+1; que.push(to); } } } return dis[sink]!=-1;}inline int Dinic(){ int res=0; for(;bfs();){ for(int i=1;i<=n;++i) work[i]=head[i]; for(;;){ for(int i=1;i<=n;++i)mark[i]=0; int f=dfs(src,INF); if(!f)break; res+=f; } } return res;}int main(){ cin>>m>>n; src=n+1,sink=n+2; for(int i=1;i<=m;++i) scanf("%d",&A[i]),last[i]=src; memset(head,-1,sizeof(head)); for(int i=1,k,s;i<=n;++i){ scanf("%d",&k); for(int j=1,a;j<=k;++j){ scanf("%d",&a); if(last[a]!=src)add_edge(last[a],i,INF); else add_edge(last[a],i,A[a]); last[a]=i; } scanf("%d",&s); add_edge(i,sink,s); } n+=2; cout<<Dinic()<<endl; return 0;}
- POJ 1149 PIGS Solution
- POJ 1149 PIGS
- poj 1149 PIGS
- POJ 1149 PIGS //MAXFLOW
- POJ 1149 PIGS
- POJ 1149 PIGS
- poj 1149 pigs
- POJ 1149 PIGS
- poj 1149 PIGS
- POJ 1149 PIGS
- POJ-1149-PIGS
- POJ 1149 PIGS
- poj 1149 : PIGS
- POJ-1149-PIGS
- Poj 1149 PIGS
- POJ-1149-PIGS
- poj(1149)PIGS
- POJ 1149 PIGS
- Linux环境下的docker简介
- LeetCode 361. Bomb Enemy
- C3P0连接池
- jquery中的each如何给元素赋值
- C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子。
- POJ 1149 PIGS Solution
- Cocos2d-x之下载安装和配置
- Arduino 卡片4呼吸灯Fading Light
- iOS9中的那些坑
- n久前的51单片机4*4键盘加4数码管显示汇编程序
- Android触摸事件分发
- usb 端点解释
- USB 基本知识
- 网页“黑手”如何入侵你的Windows系统