[网络流24题] 最长k可重线段集问题 (费用流)
最长k可重区间集问题的加强版
大体思路都一样的,不再赘述,但有一些细节需要注意
首先,坐标有负数,而且需要开$longlong$算距离
但下面才是重点:
我们把问题放到了二维平面内,如果出现了垂直于$x$轴的线段,该如何处理呢?直接当成线段处理显然不可取
假设这条线段的横坐标是$x$
1.它不会对从$x$开始的倾斜线段产生任何影响,但会和穿过$x$的倾斜直线抢位置
2.它会和同样在$x$垂直的线段抢位置
我用了一个比较笨的做法,先把横坐标离散,再把离散后的横坐标抻成原来的$2$倍,垂直线段横坐标为$2x-1$,倾斜线段横坐标是$2x$,问题就被解决了
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 2005 6 #define M1 200010 7 #define ll long long 8 #define dd double 9 #define inf 0x3f3f3f3f 10 #define maxn 100000 11 using namespace std; 12 13 int gint() 14 { 15 int ret=0,fh=1;char c=getchar(); 16 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 17 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 18 return ret*fh; 19 } 20 int n,K,S,T; 21 struct Edge{ 22 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],dis[M1<<1],cte; 23 void ae(int u,int v,int F,int D) 24 { 25 cte++; to[cte]=v; flow[cte]=F; dis[cte]=D; 26 nxt[cte]=head[u]; head[u]=cte; 27 } 28 }e; 29 30 int que[M1<<1],hd,tl,dis[N1],id[N1],flow[N1],use[N1]; 31 int spfa() 32 { 33 int x,j,v; 34 memset(dis,-1,sizeof(dis)); memset(flow,0,sizeof(flow)); memset(use,0,sizeof(use)); 35 hd=1,tl=0; que[++tl]=S; dis[S]=0; use[S]=1; flow[S]=inf; 36 while(hd<=tl) 37 { 38 x=que[hd++]; 39 for(j=e.head[x];j;j=e.nxt[j]) 40 { 41 v=e.to[j]; 42 if( e.flow[j]>0 && dis[v]<dis[x]+e.dis[j] ) 43 { 44 dis[v]=dis[x]+e.dis[j]; id[v]=j; 45 flow[v]=min(flow[x],e.flow[j]); 46 if(!use[v]) que[++tl]=v, use[v]=1; 47 } 48 } 49 use[x]=0; 50 } 51 return dis[T]!=-1; 52 } 53 int EK() 54 { 55 int tcost=0,mxflow=0,x; 56 while(spfa()) 57 { 58 mxflow+=flow[T]; tcost+=flow[T]*dis[T]; 59 for(x=T;x!=S;x=e.to[id[x]^1]) 60 { 61 e.flow[id[x]]-=flow[T]; 62 e.flow[id[x]^1]+=flow[T]; 63 } 64 } 65 return tcost; 66 } 67 68 int l[N1],r[N1],p[N1],len[N1],t[N1<<1],cnt; 69 int main() 70 { 71 scanf("%d%d",&n,&K); 72 int i,j,x,y,ma; e.cte=1; 73 for(i=1;i<=n;i++) 74 { 75 l[i]=gint(), x=gint(), r[i]=gint(), y=gint(); 76 if(l[i]>r[i]) swap(l[i],r[i]), swap(x,y); 77 len[i]=sqrt( 1ll*(r[i]-l[i])*(r[i]-l[i])+1ll*(y-x)*(y-x) ); 78 if(l[i]!=r[i]) r[i]--; else p[i]=1; 79 t[++cnt]=l[i], t[++cnt]=r[i]; 80 } 81 sort(t+1,t+cnt+1); cnt=unique(t+1,t+cnt+1)-(t+1); 82 for(i=1;i<=n;i++) 83 { 84 x=lower_bound(t+1,t+cnt+1,l[i])-t; 85 y=lower_bound(t+1,t+cnt+1,r[i])-t; 86 if(p[i]){ l[i]=x*2-1, r[i]=y*2-1; } 87 else{ l[i]=x*2; r[i]=y*2; } 88 } 89 S=0; T=cnt*2+1; 90 for(i=1;i<=n;i++) e.ae(l[i],r[i]+1,1,len[i]), e.ae(r[i]+1,l[i],0,-len[i]); 91 for(i=1;i<=cnt*2;i++) e.ae(i,i+1,K,0), e.ae(i+1,i,0,0); e.ae(S,1,K,0); e.ae(1,S,0,0); 92 printf("%d\n",EK()); 93 return 0; 94 }