【这是一个可能永远填不完的坑】网络流24题
2018-04-10 21:06
323 查看
看到那么多大佬都开坑刷题,那我也随波逐流一下。。。虽然保不准什么时候就弃掉了。。
进度:
6/24
1、餐巾计划问题(费用流)
题目传送门:https://www.luogu.org/problemnew/show/P1251
这道题还是比较思维的。。。(然而说白了都是套路)
显然我们可以把餐巾使用量看作网络的流量,把花费看作网络的费用。
这道题主要的难点就在于如何保证每天一定有ai条餐巾用,以及处理干净餐巾的来源与脏餐巾的去向。因为只能通过源汇来控制整个网络的流量(即餐巾的使用量),所以我们可以把使用一条干净餐巾的过程拆成两个部分:(1)把一条干净的餐巾流进汇点;(2)让一条脏餐巾从源点流出。
于是把一天拆成两个点,一个用来接受脏餐巾,一个用来使用干净的餐巾,然后按题意连边(把脏餐巾洗干净),跑最小费用最大流就行了。
View Code
To be continued……
进度:
6/24
1、餐巾计划问题(费用流)
题目传送门:https://www.luogu.org/problemnew/show/P1251
这道题还是比较思维的。。。(然而说白了都是套路)
显然我们可以把餐巾使用量看作网络的流量,把花费看作网络的费用。
这道题主要的难点就在于如何保证每天一定有ai条餐巾用,以及处理干净餐巾的来源与脏餐巾的去向。因为只能通过源汇来控制整个网络的流量(即餐巾的使用量),所以我们可以把使用一条干净餐巾的过程拆成两个部分:(1)把一条干净的餐巾流进汇点;(2)让一条脏餐巾从源点流出。
于是把一天拆成两个点,一个用来接受脏餐巾,一个用来使用干净的餐巾,然后按题意连边(把脏餐巾洗干净),跑最小费用最大流就行了。
#include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<ctime> #include<algorithm> #include<queue> #include<vector> #include<map> #define ll long long #define ull unsigned long long #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) #define lowbit(x) (x& -x) #define mod 1000000007 #define inf 0x3f3f3f3f #define eps 1e-18 #define maxn 1010 inline ll read(){ll tmp=0; char c=getchar(),f=1; for(;c<'0'||'9'<c;c=getchar())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=getchar())tmp=(tmp<<3)+(tmp<<1)+c-'0'; return tmp*f;} inline ll power(ll a,ll b){ll ans=0; for(;b;b>>=1){if(b&1)ans=ans*a%mod; a=a*a%mod;} return ans;} inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline void swap(int &a,int &b){int tmp=a; a=b; b=tmp;} using namespace std; struct edge{ int to,nxt,flow; }e[maxn*maxn*2+4*maxn]; int fir[2*maxn],lv[2*maxn],q[2*maxn]; int n,m,S,T,tot=0; void add(int x,int y,int flow) { e[tot].to=y; e[tot].flow=flow; e[tot].nxt=fir[x]; fir[x]=tot++; e[tot].to=x; e[tot].flow=0; e[tot].nxt=fir[y]; fir[y]=tot++; } int dfs(int now,int flow) { if(now==T)return flow; for(int i=fir[now];~i;i=e[i].nxt) if(e[i].flow&&lv[e[i].to]==lv[now]+1){ int tmp=dfs(e[i].to,min(flow,e[i].flow)); e[i].flow-=tmp; e[i^1].flow+=tmp; if(tmp)return tmp; } return 0; } int dinic() { int i,ans=0; while(1){ for(i=0;i<=T;i++)lv[i]=0; int h=1,t=1; q[1]=S; lv[S]=1; while(h<=t){ for(i=fir[q[h]];~i;i=e[i].nxt) if(e[i].flow&&!lv[e[i].to]){ q[++t]=e[i].to; lv[e[i].to]=lv[q[h]]+1; } ++h; } if(!lv[T])return ans; int k=dfs(S,inf); while(k)ans+=k,k=dfs(S,inf); } } int main() { memset(fir,255,sizeof(fir)); n=read(); m=read(); S=0; T=n+m+1; int cnt=0; for(int i=1;i<=n;i++){ int k=read(); add(S,i,k); cnt+=k; } for(int i=1;i<=m;i++){ int p=read(); while(p--)add(read(),n+i,1); add(n+i,T,1); } int ans=dinic(); if(ans<cnt)printf("No Solution!\n"); else{ for(int i=1;i<=n;i++){ printf("%d:",i); for(int j=fir[i];~j;j=e[j].nxt) if(!e[j].flow&&e[j].to!=S) printf("%d ",e[j].to-n); printf("\n"); } } }
View Code
To be continued……
相关文章推荐
- 做技术注意,操作一个步骤,永远不要相信以前的经验,因为你面临的环境可能已经发生变化,但是没有人告诉你.
- 做技术注意,操作一个步骤,永远不要相信以前的经验,因为你面临的环境可能已经发生变化,但是没有人告诉你.
- 有一个职位可能要加很多班,去不去应聘呢?
- 网络流与线性规划24题08机器人路径规划问题之初探索(未完成版)
- 一个圆的若干种可能—motion graphic中图形元素的状态表现
- Nginx + PHP CGI的一个可能的安全漏洞
- Android下写一个永远不会被KILL掉的进程/服务
- Firefox用户,一个不小心你们的密码可能已经被泄露
- 编程题:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列
- 线性规划与网络流24题の19 负载平衡问题(最小费用最大流)
- 一个简单的2级连动(实际都写烂了,做项目顺便写了一个,可能还有些不完善)
- 可能是一个很好的长期投资
- 开发一个 App 有多难?说出来你可能不信!
- 贴一个Microsoft Business Framework的图片上来,可能有些兄弟还不知道。
- pon 认证错误的一个可能的原因
- 生成一个列表,存放100个随机整数,找出出现次数最多的数字(可能不止一个)
- 网络流24题
- 将n个相异的球按每小组m个球进行分组,不足m个的也算一个小组。输出所有可能的分组方式;对其中的一种分组方式,都指明每个小组包含的球的情况!
- 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码【123和12345】那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出的电话号码(java实现)
- 浮躁的人永远不是一个高手。