1. 程式人生 > >網路流24題總結和題解P1251

網路流24題總結和題解P1251

P1251 餐巾計劃問題

首先費用流

這個題也不知道是不是我搞錯了 bzoj好像資料範圍不大對 是不是有網路流以外的做法 我也不得而知

這個題是個這樣的模型:點代表天 每個天有s種決策 就拆為s個點 構造分層圖 圖與圖之間連結操作邊(邊代表操作)

簡單來說叫做

第一類:決策拆點

難度評價 思維難度 2 程式碼難度 2 總體較為中檔

程式碼

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 4005
 4 #define ll long long
 5 #define inf 214700000
 6
struct edge{int from,to,cap,flow,cost;}; 7 int k=0;vector<edge>edges;vector<int>g[maxn]; 8 void add_edge(int f,int t,int v,int cost){g[f].push_back(k),g[t].push_back(k+1),k+=2,edges.push_back({f,t,v,0,cost}),edges.push_back({t,f,0,0,-cost});} 9 int n,m,visit[maxn],d[maxn],a[maxn],p[maxn],aa,b,c,dd,s,t,m1,t1,m2,t2,x;
10 ll sum=0,flow=0; 11 bool spfa(){for(int i=1;i<maxn;i++)d[i]=inf;a[s]=inf; 12 memset(visit,0,sizeof(visit)); 13 queue<int>q;q.push(s),d[s]=0;visit[s]=1; 14 while(!q.empty()){int u=q.front();q.pop();visit[u]=0; 15 for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]]; 16
if(d[e.to]>d[u]+e.cost&&e.cap>e.flow){p[e.to]=g[u][i],a[e.to]=min(a[u],e.cap-e.flow),d[e.to]=d[u]+e.cost; 17 if(!visit[e.to])q.push(e.to),visit[e.to]=1; 18 } 19 } 20 }if(d[t]==inf)return 0; 21 flow+=1ll*a[t]; 22 sum+=1ll*d[t]*a[t];int u=t; 23 while(u!=s){edges[p[u]].flow+=a[t];edges[p[u]^1].flow-=a[t]; 24 u=edges[p[u]].from; 25 }return true; 26 } 27 int main(){cin>>n;s=0,t=2*n+1; 28 for(int i=1;i<=n;i++){scanf("%d",&x); 29 add_edge(s,i,x,0);add_edge(i+n,t,x,0); 30 }scanf("%d%d%d%d%d",&m,&t1,&m1,&t2,&m2); 31 for(int i=1;i<=n;i++){ 32 if(i+1<=n)add_edge(i,i+1,inf,0);if(i+t1<=n)add_edge(i,i+n+t1,inf,m1); 33 if(i+t2<=n)add_edge(i,i+n+t2,inf,m2);add_edge(s,i+n,inf,m); 34 }while(spfa());cout<<sum<<endl; 35 }
View Code