题意:

思路:

【问题分析】

最大权不相交路径问题,可以用最大费用最大流解决。

【建模方法】

方法1

按左端点排序所有区间,把每个区间拆分看做两个顶点<i.a><i.b>,建立附加源S汇T,以及附加顶点S'。

1、连接S到S'一条容量为K,费用为0的有向边。

2、从S'到每个<i.a>连接一条容量为1,费用为0的有向边。

3、从每个<i.b>到T连接一条容量为1,费用为0的有向边。

4、从每个顶点<i.a>到<i.b>连接一条容量为1,费用为区间长度的有向边。

5、对于每个区间i,与它右边的不相交的所有区间j各连一条容量为1,费用为0的有向边。

求最大费用最大流,最大费用流值就是最长k可重区间集的长度。

方法2

离散化所有区间的端点,把每个端点看做一个顶点,建立附加源S汇T。

1、从S到顶点1(最左边顶点)连接一条容量为K,费用为0的有向边。

2、从顶点2N(最右边顶点)到T连接一条容量为K,费用为0的有向边。

3、从顶点i到顶点i+1(i+1<=2N),连接一条容量为无穷大,费用为0的有向边。

4、对于每个区间[a,b],从a对应的顶点i到b对应的顶点j连接一条容量为1,费用为区间长度的有向边。

求最大费用最大流,最大费用流值就是最长k可重区间集的长度。

【建模分析】

这个问题可以看做是求K条权之和最大的不想交路径,每条路径为一些不相交的区间序列。由于是最大费用流,两条路径之间一定有一些区间相交,可以看做事相交部分重复了2次,而K条路经就是最多重

复了K次。最简单的想法就是把区间排序后,不相交的区间之间连接一条边,由于每个区间只能用一次,所以要拆点,点内限制流量。如果我们改变一下思路,把端点作为网络中的顶点,区间恰恰是特定

一些端点之间的边,这样建模的复杂度更小。方法1的边数是O(N^2)的,而方法2的边数是O(N)的,可以解决更大规模的问题。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 50000
#define M 1000000
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const ll MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; struct node
{
int x,y;
}a[N]; int head[N],vet[N],nxt[N],len1[N],len2[N],dis[N],inq[N],q[N],pre[N][],c[N],
s,S,T,tot,ans1,ans2; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b,int c,int d)
{
nxt[++tot]=head[a];
vet[tot]=b;
len1[tot]=c;
len2[tot]=d;
head[a]=tot; nxt[++tot]=head[b];
vet[tot]=a;
len1[tot]=;
len2[tot]=-d;
head[b]=tot;
} int spfa()
{
rep(i,,s)
{
dis[i]=-INF;
inq[i]=;
}
int t=,w=;
q[]=S; dis[S]=; inq[S]=;
while(t<w)
{
t++; int u=q[t%(s+)]; inq[u]=;
int e=head[u];
while(e)
{
int v=vet[e];
if(len1[e]&&dis[u]+len2[e]>dis[v])
{
dis[v]=dis[u]+len2[e];
pre[v][]=u;
pre[v][]=e;
if(!inq[v])
{
w++; q[w%(s+)]=v; inq[v]=;
}
}
e=nxt[e];
}
}
if(dis[T]==-INF) return ;
return ;
} void mcf()
{
int k=T,t=INF;
while(k!=S)
{
int e=pre[k][];
t=min(t,len1[e]);
k=pre[k][];
}
ans1+=t;
k=T;
while(k!=S)
{
int e=pre[k][];
len1[e]-=t;
len1[e^]+=t;
ans2+=t*len2[e];
k=pre[k][];
}
} int main()
{
//freopen("1.in","r",stdin);
int n=read(),K=read();
int m=;
rep(i,,n)
{
a[i].x=read(),a[i].y=read();
c[++m]=a[i].x;
c[++m]=a[i].y;
}
sort(c+,c+m+);
int k=unique(c+,c+m+)-c-;
s=k,S=++s,T=++s;
rep(i,,s) head[i]=;
tot=;
rep(i,,n)
{
int len=a[i].y-a[i].x;
a[i].x=lower_bound(c+,c+k+,a[i].x)-c;
a[i].y=lower_bound(c+,c+k+,a[i].y)-c;
add(a[i].x,a[i].y,,len);
}
rep(i,,k-) add(i,i+,K,);
add(S,,K,);
add(k,T,K,);
ans1=ans2=;
while(spfa()) mcf();
printf("%d\n",ans2);
return ; }

最新文章

  1. 函数式Android编程(II):Kotlin语言的集合操作
  2. C#使用HttpWebRequest 进行请求,提示 基础连接已经关闭: 发送时发生错误。
  3. IntelliJ IDEA设置JVM运行参数
  4. 编写Java应用程序。首先,定义一个Print类,它有一个方法void output(int x),如果x的值是1,在控制台打印出大写的英文字母表;如果x的值是2,在 控制台打印出小写的英文字母表。其次,再定义一个主类——TestClass,在主类 的main方法中创建Print类的对象,使用这个对象调用方法output ()来打印出大 小写英文字母表。
  5. js正则标志/g /i /m的用法,以及实例
  6. Android || IOS录制mp3语音文件方法
  7. 转:PHP分页技术的代码和示例
  8. Yii2.0 UrlManager
  9. 随记一个C的时间加减
  10. margin与padding的bug
  11. 开源的许可证GPL、LGPL、BSD、Apache 2.0
  12. SQL-27 给出每个员工每年薪水涨幅超过5000的员工编号emp_no、薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列。 提示:在sqlite中获取datetime时间对应的年份函数为strftime(&#39;%Y&#39;, to_date)
  13. java-SimpleDateFormat类
  14. 如何给mysql用户分配权限
  15. C语言:返回两个数组中第一个元素的指针,并输出这个值
  16. Singular value encountered in calculation for ROI
  17. Centos 7 minimal install 后的基础配置
  18. Linux 最好是禁用IPV6
  19. c# SocketAsyncEventArgs类的使用 IOCP服务器
  20. VirtualBox安装虚拟机全过程

热门文章

  1. ssh远程登录过程中卡住
  2. postfix无法启动问题
  3. [转帖]Oracle 查询各表空间使用情况--完善篇
  4. ES5中的继承
  5. C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)(转)
  6. 自己手动用原生实现bind/call/apply
  7. 《剑指offer》面试题24 二叉搜索树的后序遍历序列 Java版
  8. C++中的析构顺序和cosnt对象
  9. SCUT - 484 - 平面上的点 - 数据结构
  10. php strpos() 函数介绍与使用方法详解