1246-Concert Hall Scheduling
問題概要
2つの同一のコンサートホールを運営することになった.
[i,j]日の間コンサートホールを借りるのにw円支払うという情報が与えられるので,利益が最大になるようにせよ
解法
最小費用流.DPでも解けるらしい.
実装(C++)
#include <iostream> #include <vector> #include <algorithm> using namespace std; const int V_MAX=400; const int INF=99999999; struct Edge{ int dst,weight,capacity,rev; }; int V; vector<Edge> G[V_MAX]; void add_edge(int s,int d,int c,int f){ G[s].push_back((Edge){d,c,f,G[d].size()}); G[d].push_back((Edge){s,-c,0,G[s].size()-1}); } //最小費用流 int min_cost_flow(int src,int dst,int flow){ int res=0; while(flow>0){ vector<int> dist(V,INF); vector<int> backv(V,INF); vector<int> backe(V,INF); bool update=true; dist[src]=0; while(update){ update=false; for(int i=0;i<V;i++){ if(dist[i]<INF){ for(int j=0;j<(int)G[i].size();j++){ Edge &e=G[i][j]; if(e.capacity==0)continue; if(dist[e.dst]>dist[i]+e.weight){ dist[e.dst]=dist[i]+e.weight; backv[e.dst]=i; backe[e.dst]=j; update=true; } } } } } if(dist[dst]==INF){ return -1; } //出来るだけ流す int f=flow; int now=dst; while(now!=src){ f=min(f,G[backv[now]][backe[now]].capacity); now=backv[now]; } //f流せるはずなので流してみる now=dst; while(now!=src){ res+=G[backv[now]][backe[now]].weight*f; G[backv[now]][backe[now]].capacity-=f; G[now][G[backv[now]][backe[now]].rev].capacity+=f; now=backv[now]; } flow-=f; } return res; } void init(){ for(int i=0;i<V_MAX;i++)G[i].clear(); } int main() { int n; while(cin>>n,n){ V=366; init(); for(int i=0;i<n;i++){ int a,b,w; cin>>a>>b>>w; a--; add_edge(a,b,-w,1); } for(int i=0;i<365;i++){ add_edge(i,i+1,0,2); } cout<<-min_cost_flow(0,365,2)<<endl; } return 0; }