最长k可重线段集问题

和最长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;
}

猜你喜欢

转载自www.cnblogs.com/sdfzhsz/p/9286799.html