其实和最长k可重区间集问题差不多诶……
把这条开线段给压成x轴上的一条线段,然后按上面说的那种方法做即可
然而有一个坑点是线段可以垂直于x轴,然后一压变成一个点,连上正权环,求最长路……然后spfa他就死了……
怎么解决呢……把每一个区间的左右端点坐标扩大两倍,如果相等就$--l[i]$,否则$++l[i]$,这样的话能保证本来不能覆盖的点仍不能覆盖,本来可以覆盖的点仍可以覆盖
似乎讲不清楚……感性理解一下好了……
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<queue> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #define inf 0x3f3f3f3f 9 #define ll long long 10 using namespace std; 11 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 12 char buf[1<<21],*p1=buf,*p2=buf; 13 inline int read(){ 14 #define num ch-'0' 15 char ch;bool flag=0;int res; 16 while(!isdigit(ch=getc())) 17 (ch=='-')&&(flag=true); 18 for(res=num;isdigit(ch=getc());res=res*10+num); 19 (flag)&&(res=-res); 20 #undef num 21 return res; 22 } 23 const int N=1005,M=4005; 24 int ver[M],Next[M],head[N],edge[M],flow[M],tot=1; 25 int dis[N],disf[N],vis[N],Pre[N],last[N],n,s,t,k; 26 inline ll sqr(int x){return 1ll*x*x;} 27 inline void add(int u,int v,int f,int e){ 28 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e; 29 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=0,edge[tot]=-e; 30 } 31 queue<int> q; 32 bool spfa(){ 33 memset(dis,0xef,sizeof(dis)); 34 q.push(s),dis[s]=0,disf[s]=inf,Pre[t]=-1; 35 while(!q.empty()){ 36 int u=q.front();q.pop();vis[u]=0; 37 for(int i=head[u];i;i=Next[i]){ 38 int v=ver[i]; 39 if(flow[i]&&dis[v]<dis[u]+edge[i]){ 40 dis[v]=dis[u]+edge[i],Pre[v]=u,last[v]=i; 41 disf[v]=min(disf[u],flow[i]); 42 if(!vis[v]) vis[v]=1,q.push(v); 43 } 44 } 45 } 46 return ~Pre[t]; 47 } 48 ll dinic(){ 49 int maxflow=0;ll maxcost=0; 50 while(spfa()){ 51 int u=t; 52 maxflow+=disf[t],maxcost+=1ll*disf[t]*dis[t]; 53 while(u!=s){ 54 flow[last[u]]-=disf[t]; 55 flow[last[u]^1]+=disf[t]; 56 u=Pre[u]; 57 } 58 } 59 return maxcost; 60 } 61 int l[N],r[N],x[N],y[N],st[N],val[N],m=0; 62 int main(){ 63 n=read(),k=read(); 64 for(int i=1;i<=n;++i){ 65 l[i]=read(),x[i]=read(),r[i]=read(),y[i]=read(); 66 val[i]=sqrt(sqr(y[i]-x[i])+sqr(r[i]-l[i])); 67 l[i]*=2,r[i]*=2; 68 l[i]==r[i]?(--l[i]):(++l[i]); 69 st[++m]=l[i],st[++m]=r[i]; 70 } 71 sort(st+1,st+1+m); 72 m=unique(st+1,st+1+m)-st-1; 73 s=0,t=m+1; 74 for(int i=s;i<t;++i) add(i,i+1,k,0); 75 for(int i=1;i<=n;++i){ 76 l[i]=lower_bound(st+1,st+1+m,l[i])-st; 77 r[i]=lower_bound(st+1,st+1+m,r[i])-st; 78 add(l[i],r[i],1,val[i]); 79 } 80 printf("%lld ",dinic()); 81 return 0; 82 }