P2050-[NOI2012]美食节【费用流,动态连边】
生活随笔
收集整理的這篇文章主要介紹了
P2050-[NOI2012]美食节【费用流,动态连边】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P2050
題目大意
nnn個菜品mmm個廚師,第iii種菜需要pip_ipi?份,第iii個人做第jjj道菜需要時間ti,jt_{i,j}ti,j?,求最少等待時間和。
解題思路
這題和之前修車很像,數據變大了。
考慮網絡流,如果一個廚師總共要做kkk個菜,那么第iii個菜的時間貢獻就是(k?i+1)?t(k-i+1)*t(k?i+1)?t,反過來看,做倒數第iii道菜的時間貢獻就是i?ti*ti?t。
也就是如果目前廚師要做kkk道菜,那么在最開頭加入一個新菜時需要增加的時間就是(k+1)?t(k+1)*t(k+1)?t。
定義點陣(i,j)(i,j)(i,j)表示第iii個廚師做到第jjj道菜,然后和顧客構建二分圖,聯(lián)向第jjj道菜的費用乘上jjj即可,因為是最小費用所以肯定會優(yōu)先把小費用的邊流掉。
這樣正確性已經保證,但是空間復雜度顯然不行。考慮動態(tài)連邊,因為肯定會先流小費用,所以當小費用的有流時在動態(tài)加入更大費用的一條邊即可。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define p1(x,y) (((x)-1)*K+(y)) #define p2(x) (p1(m,K)+(x)) using namespace std; const int N=1e5+10; struct node{int to,next,w,c; }a[N*70]; int n,m,ans,tot=1,s,t,K; int e[50][110],k[50]; int ls[N],f[N],mf[N],pre[N],mark[N]; bool v[N]; queue<int> q; void addl(int x,int y,int w,int c){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;a[tot].c=c;a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;a[tot].c=-c;return; } bool SPFA(){memset(f,0x3f,sizeof(f));f[s]=0;q.push(s);v[s]=1;mf[s]=2147483647;while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(a[i].w&&f[x]+a[i].c<f[y]){f[y]=f[x]+a[i].c;mf[y]=min(mf[x],a[i].w);pre[y]=i;if(!v[y]){v[y]=1;q.push(y);}}}v[x]=0;}return f[t]<=2147483647/3; } void updata(){int x=t;while(x!=s){a[pre[x]].w-=mf[t];a[pre[x]^1].w+=mf[t];if(x==t&&(a[pre[x]^1].to%K)>0){int y=a[pre[x]^1].to;int c=y%K+1,pos=mark[y];for(int i=1;i<=n;i++)addl(p2(i),p1(pos,c),1,e[i][pos]*c);addl(p1(pos,c),t,1,0);mark[p1(pos,c)]=pos;}x=a[pre[x]^1].to;}ans+=mf[t]*f[t]; } void net_flow(){while(SPFA())updata(); } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&k[i]),K+=k[i];for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&e[i][j]);s=p2(n)+1;t=s+1;for(int i=1;i<=n;i++)addl(s,p2(i),k[i],0),mark[p2(i)]=i;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++)addl(p2(j),p1(i,1),1,e[j][i]);addl(p1(i,1),t,1,0);mark[p1(i,1)]=i;}net_flow();printf("%d",ans); }總結
以上是生活随笔為你收集整理的P2050-[NOI2012]美食节【费用流,动态连边】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P3338-[ZJOI2014]力【FF
- 下一篇: P2824-[HEOI2016/TJOI