网络流24题-最长k可重区间集问题
时空限制1000ms / 128MB
题目描述
对于给定的开区间集合 I 和正整数 k,计算开区间集合 I 的最长 k可重区间集的长度。
输入输出格式
输入格式:第 1 行有 2 个正整数 n和 k,分别表示开区间的个数和开区间的可重迭数。接下来的 n行,每行有 2 个整数,表示开区间的左右端点坐标。
输出格式:将计算出的最长 k可重区间集的长度输出
输入输出样例
说明
对于100%的数据,1≤n≤500,1≤k≤3
最大权不相交路径问题。这个题目可以看做是求K条权之和最大的不相交路径,每条路径为一些不相交的区间序列
参考博客:https://blog.csdn.net/lvshubao1314/article/details/32914805
#include<bits/stdc++.h> #define INF LLONG_MAX/2 #define N 2000 using namespace std; typedef struct { int u,v; long long flow,cost; }ss; ss edg[2*N]; vector<int>edges[N]; int now_edge=0; void addedge(int u,int v,long long flow,long long cost) { edges[u].push_back(now_edge); edg[now_edge++]=(ss){u,v,flow,cost}; edges[v].push_back(now_edge); edg[now_edge++]=(ss){v,u,0,-cost}; } bool spfa(int s,int t,long long &flow,long long &cost) { long long dis[N]; for(int i=0;i<N;i++)dis[i]=INF; dis[s]=0; int vis[N]={0}; vis[s]=1; queue<int>q; q.push(s); long long addflow[N]={0}; addflow[s]=INF; int pre[N]={0}; while(!q.empty()) { int now=q.front(); q.pop(); vis[now]=0; int Size=edges[now].size(); for(int i=0;i<Size;i++) { ss e=edg[edges[now][i]]; if(e.flow>0&&dis[e.v]>dis[now]+e.cost) { dis[e.v]=dis[now]+e.cost; addflow[e.v]=min(addflow[now],e.flow); pre[e.v]=edges[now][i]; if(!vis[e.v]) { q.push(e.v); vis[e.v]=1; } } } } if(dis[t]==INF)return false; flow+=addflow[t]; cost+=addflow[t]*dis[t]; int now=t; while(now!=s) { edg[pre[now]].flow-=addflow[t]; edg[pre[now]^1].flow+=addflow[t]; now=edg[pre[now]].u; } return true; } void MCMF(int s,int t,long long &flow,long long &cost) { while(spfa(s,t,flow,cost)); } struct { int l,r,value; }arr[N]; int lsh[N],len_lsh; int f(int x) { return lower_bound(lsh,lsh+len_lsh,x)-lsh+1; } void init() { for(int i=0;i<N;i++)edges[i].clear(); now_edge=0; len_lsh=0; } int main() { int t=1; //scanf("%d",&t); while(t--) { init(); int n,k,m; scanf("%d %d",&m,&k); for(int i=0;i<m;i++) { scanf("%d %d",&arr[i].l,&arr[i].r); arr[i].value=arr[i].r-arr[i].l; lsh[len_lsh++]=arr[i].l; lsh[len_lsh++]=arr[i].r; } sort(lsh,lsh+len_lsh); len_lsh=unique(lsh,lsh+len_lsh)-lsh; int s=len_lsh+1,t=len_lsh+2; addedge(s,1,k,0); addedge(len_lsh,t,INF,0); for(int i=1;i<len_lsh;i++)addedge(i,i+1,INF,0); for(int i=0;i<m;i++)addedge(f(arr[i].l),f(arr[i].r),1,-arr[i].value); long long cost=0,flow=0; MCMF(s,t,flow,cost); printf("%lld\n",-cost); } return 0; }
路漫漫其修远兮,吾将上下而求索