zoukankan      html  css  js  c++  java
  • 网络流24题之最长k可重线段集问题

    对于每个线段拆成两个点,如同之前一样建图,由于可能出现垂直于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
    ",-cost);
    74     return 0;
    75 }
  • 相关阅读:
    初学者之 Git 和 Github
    80端口与8080端口是两种不同的端口吗?他们到底有什么区别和联系?
    redis 基础(一) 初步了解redis
    spring 基础(四)浏览器跨域访问+拦截器(Interceptor)
    mysql商业版和社区版
    spring 基础(五) spring mvc RESTful
    解决idea控制台打印乱码问题
    springBoot 基础-拓展(二) 记录一些常用的配置文件
    SpringBoot 基础(零) SpringBoot和Spring
    springBoot 基础-拓展(一) spring-boot-starter
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8400477.html
Copyright © 2011-2022 走看看