对于每个线段拆成两个点,如同之前一样建图,由于可能出现垂直于x轴的
所以建图由i指向i~
继续最小费用最大流
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=10000005,inf=1e9; 4 int head[N],d[N],f[N],l1[N],r1[N],l2[N],r2[N],a[N],s=1e9,t,n,k,cnt=-1; 5 long long cost; 6 bool v[N]; 7 struct node{ 8 int to,nex,f,w,c; 9 }e[1000005]; 10 void add(int x,int y,int w,int c) 11 { 12 e[++cnt].to=y;e[cnt].w=w;e[cnt].f=x;e[cnt].c=c;e[cnt].nex=head[x];head[x]=cnt; 13 e[++cnt].to=x;e[cnt].w=0;e[cnt].f=y;e[cnt].c=-c;e[cnt].nex=head[y];head[y]=cnt; 14 } 15 queue<int>q; 16 bool spfa() 17 { 18 memset(f,-1,sizeof(f)); 19 memset(d,0x3f,sizeof(d)); 20 memset(v,0,sizeof(v)); 21 d[s]=0;v[s]=1;q.push(s); 22 while(!q.empty()) 23 { 24 int x=q.front();q.pop();v[x]=0; 25 for(int i=head[x];i!=-1;i=e[i].nex) 26 { 27 int y=e[i].to; 28 if(d[y]<=d[x]+e[i].c||!e[i].w)continue; 29 30 d[y]=d[x]+e[i].c;f[y]=i; 31 if(!v[y])q.push(y),v[y]=1; 32 } 33 } 34 if(d[t]>1e9)return 0; 35 int flow=inf; 36 for(int i=f[t];i!=-1;i=f[e[i].f]) 37 flow=min(flow,e[i].w); 38 for(int i=f[t];i!=-1;i=f[e[i].f]) 39 e[i].w-=flow,e[i^1].w+=flow,cost+=1ll*e[i].c*flow; 40 return 1; 41 } 42 int main() 43 { 44 scanf("%d%d",&n,&k);int num=0; 45 memset(head,-1,sizeof(head)); 46 for(int i=1;i<=n;++i) 47 { 48 scanf("%d%d%d%d",&l1[i],&r1[i],&l2[i],&r2[i]); 49 a[++num]=l1[i];a[++num]=l2[i]; 50 } 51 sort(a+1,a+1+num); 52 num=unique(a+1,a+1+num)-a-1; 53 for(int i=1;i<=n;++i) 54 { 55 int x=sqrt(1ll*(l1[i]-l2[i])*(l1[i]-l2[i])+1ll*(r2[i]-r1[i])*(r2[i]-r1[i])); 56 l1[i]=lower_bound(a+1,a+1+num,l1[i])-a; 57 l2[i]=lower_bound(a+1,a+1+num,l2[i])-a; 58 if(l1[i]!=l2[i]) 59 add((l1[i]<<1)|1,l2[i]<<1,1,-x); 60 else 61 add(l1[i]<<1,(l2[i]<<1)|1,1,-x); 62 } 63 for(int i=1;i<num;++i) 64 { 65 add((i<<1)|1,i+1<<1,inf,0); 66 add(i<<1,(i<<1)|1,inf,0); 67 } 68 add(num<<1,(num<<1)|1,inf,0); 69 t=num*2+10; 70 add((num<<1)|1,t,k,0); 71 add(0,2,k,0);s=0; 72 while(spfa()); 73 printf("%lld\n",-cost); 74 return 0; 75 }
原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8400477.html
时间: 2024-10-03 07:57:17