POJ3762 The Bonus Salary! (费用流+离散化)
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <cmath> #include <vector> #include <algorithm> #include <limits.h> using namespace std; #define inf 1e8 #define maxn 4005 #define maxm 100005 int head[maxn],eid; int dis[maxn]; bool vis[maxn]; int a[maxn]; int pre[maxn]; struct node { int u,v,cap,next,cost; }eg[maxm]; void add(int u,int v,int cap,int cost) { eg[eid].u=u; eg[eid].v=v; eg[eid].cap=cap; eg[eid].next=head[u]; eg[eid].cost=cost; head[u]=eid++; eg[eid].u=v; eg[eid].v=u; eg[eid].cap=0; eg[eid].next=head[v]; eg[eid].cost=-cost; head[v]=eid++; } bool spfa(int s,int t,int &flow,int &cost) { memset(vis,false,sizeof(vis)); for(int i=0;i<maxn;i++) dis[i]=inf; dis[s]=0; vis[s]=true; pre[s]=0; a[s]=inf; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=false; for(int i=head[u];i!=-1;i=eg[i].next) { if(eg[i].cap&&dis[eg[i].v]>dis[u]+eg[i].cost) { dis[eg[i].v]=dis[u]+eg[i].cost; pre[eg[i].v]=i; a[eg[i].v]=min(a[u],eg[i].cap); if(!vis[eg[i].v]) { q.push(eg[i].v); vis[eg[i].v]=true; } } } } if(dis[t]==inf) return false; flow+=a[t]; cost+=dis[t]*a[t]; int u=t; while(u!=s) { eg[pre[u]].cap-=a[t]; eg[pre[u]^1].cap+=a[t]; u=eg[pre[u]].u; } return true; } int mincost(int s,int t) { int flow=0,cost=0; while(spfa(s,t,flow,cost)); return cost; } void init() { memset(head,-1,sizeof(head)); eid=0; } int t1[maxn],t2[maxn],t3[maxn*2],t4[maxn*2],v[maxn]; int main() { //freopen("in.txt","r",stdin); int n,m,x,y,z; while(~scanf("%d%d",&n,&m)) { init(); for(int i=0;i<n;i++) { scanf("%2d:%2d:%2d",&x,&y,&z); t1[i]=x*10000+y*100+z; t3[i*2]=t1[i]; scanf("%2d:%2d:%2d",&x,&y,&z); t2[i]=x*10000+y*100+z; t3[i*2+1]=t2[i]; scanf("%d",&v[i]); } sort(t3,t3+n*2); int tot=1; for(int i=0;i<n*2;i++) { t4[tot++]=t3[i]; while(i+1<n*2&&t3[i+1]==t3[i]) i++; } if(t4[tot-1]==t4[tot-2]) tot--; for(int i=0;i<n;i++) { int flag=0; for(int j=1;j<tot;j++) { if(t1[i]==t4[j]) { t1[i]=j; flag++; } if(t2[i]==t4[j]) { t2[i]=j; flag++; } if(flag==2) break; } } for(int i=0;i<tot;i++) add(i,i+1,m,0); for(int i=0;i<n;i++) add(t1[i],t2[i],1,-v[i]); printf("%d\n",-mincost(0,tot)); } return 0; }