和最长k可重区间集问题一样。
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
#define int long long
const int N=10005,S=10003,T=10004,inf=0x3f3f3f3f3f3f3f3f,S1=10003;
struct Seg{
int s,t,len;
};
using namespace std;
int tp[N],cnt;
vector<Seg> seg;
int n,k,head[N],ecnt=1,l[N],r[N],from[N],maxflow,mincost,dis[N];
bool inq[N];
struct Edge {
int to,nxt,val,cost,from;
} e[505*505+505*2];
void add(int bg,int ed,int val,int cost) {
e[++ecnt].cost=cost;
e[ecnt].from=bg;
e[ecnt].nxt=head[bg];
e[ecnt].to=ed;
e[ecnt].val=val;
head[bg]=ecnt;
}
void insert(int bg,int ed,int val,int cost) {
cost=-cost;
add(bg,ed,val,cost);
add(ed,bg,0,-cost);
}
queue<int>qu;
bool spfa() {
qu.push(S);
std::memset(dis,0x3f,sizeof dis);
dis[S]=0;
inq[S]=1;
while(!qu.empty()) {
int u=qu.front();
qu.pop();
inq[u]=0;
for(int i=head[u],v; i; i=e[i].nxt) {
v=e[i].to;
if(dis[v]>dis[u]+e[i].cost&&e[i].val) {
dis[v]=dis[u]+e[i].cost;
from[v]=i;
if(!inq[v]) qu.push(v),inq[v]=1;
}
}
}
return dis[T]!=inf;
}
void min(int &x,int y) {
x=x<y?x:y;
}
void mcf() {
int x=inf,i=from[T];
while(i) {
min(x,e[i].val);
i=from[e[i].from];
}
maxflow+=x;
i=from[T];
while(i) {
e[i].val-=x;
e[i^1].val+=x;
mincost-=x*e[i].cost;
i=from[e[i].from];
}
}
double getlen(int xa,int ya,int xb,int yb) {
return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
}
signed main() {
cin>>n>>k;
for(int i=0,xa,xb,ya,yb;i<n;i++) {
scanf("%lld%lld%lld%lld",&xa,&ya,&xb,&yb);
int len=getlen(xa,ya,xb,yb);
if(xa>xb) swap(xa,xb);
xa<<=1,xb<<=1;
if(xa==xb) xb|=1;
else xa|=1;
tp[++cnt]=xa,tp[++cnt]=xb,seg.push_back({xa,xb,len});
}
sort(tp+1,tp+cnt+1);
int u=unique(tp+1,tp+1+cnt)-tp-1;
for(int i=0;i<seg.size();i++) {
seg[i].s=lower_bound(tp+1,tp+1+u,seg[i].s)-tp;
seg[i].t=lower_bound(tp+1,tp+1+u,seg[i].t)-tp;
}
insert(S,1,k,0);
for(int i=0;i<u;i++) insert(i,i+1,inf,0);
for(int i=0;i<seg.size();i++) insert(seg[i].s,seg[i].t,1,seg[i].len);
insert(u,T,inf,0);
while(spfa())mcf();
printf("%lld",mincost);
return 0;
}