zoukankan      html  css  js  c++  java
  • 「网络流24题」「LuoguP3358」 最长k可重区间集问题(费用流

    题目描述

    对于给定的开区间集合 I 和正整数 k,计算开区间集合 I 的最长 k可重区间集的长度。

    输入输出格式

    输入格式:

    的第 1 行有 2 个正整数 n和 k,分别表示开区间的个数和开区间的可重迭数。接下来的 n行,每行有 2 个整数,表示开区间的左右端点坐标。

    输出格式:

    将计算出的最长 k可重区间集的长度输出

    输入输出样例

    输入样例#1: 复制
    4 2
    1 7
    6 8
    7 10
    9 13 
    输出样例#1: 复制
    15

    说明

    对于100%的数据,1<=n<=500,1<=k<=3

    题解

    建图:从$S$往$L$左端点连容量为k,费用为0;

    从$L$上每个点$i$往点$i+1$连容量为INF,费用为0;

    从$L$右端点往$T$连容量INF,费用为0。

    >然后从每个区间的左端点往右端点连边,容量为1,费用为右端点$-$左端点(这道题区间长度的定义是右端点$-$左端点

    然后跑最大费用最大流就行啦~

    这样跑出来的费用会尽量大,而因为S处控制了流量,最大流就是k。

    答案就是费用。

    然后最大费用最大流就是把费用存负,跑最小费用最大流,输出答案的时候再取反就行了。

    然后这道题长度没个范围,所以还要搞个离散。

      1 /*
      2     qwerta
      3     P3358 最长k可重区间集问题
      4     Accepted
      5     100
      6     代码 C++,2.16KB
      7     提交时间 2018-10-09 18:19:08
      8     耗时/内存
      9     31ms, 936KB
     10 */
     11 #include<algorithm>
     12 #include<iostream>
     13 #include<cstring>
     14 #include<cstdio>
     15 #include<cmath>
     16 #include<queue>
     17 using namespace std;
     18 const int INF=2e9;
     19 struct emm{
     20     int e,f,v,c;
     21 }a[4003];
     22 int h[1003];
     23 int tot=1;
     24 void con(int x,int y,int v,int c)
     25 {
     26     a[++tot].f=h[x];
     27     h[x]=tot;
     28     a[tot].e=y;
     29     a[tot].v=v;
     30     a[tot].c=c;
     31     a[++tot].f=h[y];
     32     h[y]=tot;
     33     a[tot].e=x;
     34     a[tot].c=-c;
     35     return;
     36 }
     37 struct ahh{
     38     int l,r;
     39 }b[503];
     40 int ls[1003];
     41 int s,t;
     42 queue<int>q;
     43 bool sf[1003];
     44 int dis[1003];
     45 inline bool spfa()
     46 {
     47     memset(sf,0,sizeof(sf));
     48     memset(dis,127,sizeof(dis));
     49     sf[s]=1;dis[s]=0;q.push(s);
     50     while(!q.empty())
     51     {
     52         int x=q.front();q.pop();
     53         for(int i=h[x];i;i=a[i].f)
     54         if(dis[a[i].e]>dis[x]+a[i].c&&a[i].v)
     55         {
     56             dis[a[i].e]=dis[x]+a[i].c;
     57             if(!sf[a[i].e])
     58             {
     59                 sf[a[i].e]=1;
     60                 q.push(a[i].e);
     61             }
     62         }
     63         sf[x]=0;
     64     }
     65     return dis[t]<INF;
     66 }
     67 long long ans=0;
     68 int dfs(int x,int al)
     69 {
     70     sf[x]=1;
     71     if(x==t||!al)return al;
     72     int fl=0;
     73     for(int i=h[x];i;i=a[i].f)
     74     if(dis[a[i].e]==dis[x]+a[i].c&&a[i].v&&!sf[a[i].e])
     75     {
     76         int f=dfs(a[i].e,min(al,a[i].v));
     77         if(f)
     78         {
     79             fl+=f;
     80             al-=f;
     81             ans+=f*a[i].c;
     82             a[i].v-=f;
     83             a[i^1].v+=f;
     84             if(!al)break;
     85         }
     86     }
     87     if(!fl)dis[x]=-INF;
     88     return fl;
     89 }
     90 int main()
     91 {
     92     //freopen("a.in","r",stdin);
     93     int n,k;
     94     scanf("%d%d",&n,&k);
     95     int tol=0;
     96     for(int i=1;i<=n;++i)
     97     {
     98         scanf("%d%d",&b[i].l,&b[i].r);
     99         ls[++tol]=b[i].l;
    100         ls[++tol]=b[i].r;
    101     }
    102     //离散
    103     sort(ls+1,ls+tol+1);
    104     int len=(unique(ls+1,ls+tol+1)-ls)-1;//用unique去重
    105     for(int i=1;i<=n;++i)
    106     {
    107         int ll=lower_bound(ls+1,ls+len+1,b[i].l)-ls;
    108         int rr=lower_bound(ls+1,ls+len+1,b[i].r)-ls;
    109         con(ll,rr,1,-(b[i].r-b[i].l));//建边
    110     }
    111     //
    112     s=0,t=len+1;
    113     for(int i=1;i<len;++i)
    114     con(i,i+1,INF,0);
    115     con(s,1,k,0);
    116     con(len,t,INF,0);
    117     //
    118     while(spfa())
    119     {
    120         sf[t]=1;
    121         while(sf[t])
    122         {
    123             memset(sf,0,sizeof(sf));
    124             dfs(s,INF);
    125         }
    126     }
    127     cout<<-ans;//输出再取个负就好了
    128     return 0;
    129 }
  • 相关阅读:
    Number Two
    蝴蝶结
    webug3.0靶场渗透基础Day_1
    SQL SERVER2014的安装
    SQLILABS学习笔记(一)
    关于暴力破解的一些学习笔记(pikachu)
    sql注入学习笔记
    CSRF与平行越权的区别
    任意文件下载(pikachu)
    XSS跨站脚本攻击学习笔记(pikachu)
  • 原文地址:https://www.cnblogs.com/qwerta/p/9769384.html
Copyright © 2011-2022 走看看