• 最长k可重区间集


     

    P3358 最长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%的数据,1n500 ,1k3。

    这个题貌似之前不停地打开然后放弃掉。。貌似主要原因是看不懂题面让我干些什么。。。上午的考试让我有了充足的时间观察题面,发现道理就是给了一堆区间,然后每个点不能被超过k个区间覆盖,每个区间的价值是它的长度,求最大价值。

    然后一开始的时候一直都是想着怎么把互相覆盖这个条件把握好,然后各种如果他们有交集就连边之类的。。。后来发现并不可行,总是无法维护好。

    然后看了题解豁然开朗,貌似自己的拆点连边什么的都没什么问题,甚至伪超级源这种东西都想到了,然而思路还是局限了我,这个题要向与自己没有交集的区间连边。然后去跑最大费用即可。。。真是可惜了。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<map>
    #define ll long long
    #define inf 50000000
    #define re register
    #define min(a,b) a<b?a:b
    using namespace std;
    struct po{
        int nxt,to,w,dis;
    };
    po edge[250001];
    struct len{
        int l,r;
    };
    len a[1002];
    int head[1050],num=-1,n,m,s,t,k,S;
    int dis[1050],b[1050],tot;
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    inline void add_edge(int from,int to,int w,int dis)
    {
        edge[++num].nxt=head[from];
        edge[num].to=to;
        edge[num].w=w;
        edge[num].dis=dis;
        head[from]=num;
    }
    inline void add(int from,int to,int w,int dis)
    {
        add_edge(from,to,w,dis);
        add_edge(to,from,0,-dis);
    }
    inline bool spfa()
    {
        memset(dis,50,sizeof(dis));
        memset(b,0,sizeof(b));
        deque<int> q;
        dis[t]=0;
        b[t]=1;
        q.push_back(t);
        while(!q.empty()){
            int u=q.front();
            q.pop_front();
            b[u]=0;
            for(re int i=head[u];i!=-1;i=edge[i].nxt){
                int v=edge[i].to;
                if(edge[i^1].w>0&&dis[v]>dis[u]-edge[i].dis){
                    dis[v]=dis[u]-edge[i].dis;
                    if(!b[v]){
                        b[v]=1;
                        if(!q.empty()&&dis[v]<dis[q.front()])
                        q.push_front(v);
                        else
                        q.push_back(v);
                    }
                }
            }
        }
        return dis[s]<inf;
    }
    inline int dfs(int u,int low)
    {
        b[u]=1;
        if(u==t)
        return low;
        int diss=0;
        for(re int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            if(edge[i].w&&!b[v]&&dis[v]==dis[u]-edge[i].dis){
                int check=dfs(v,min(low,edge[i].w));
                if(check){
                    tot+=edge[i].dis*check;
                    low-=check;
                    diss+=check;
                    edge[i].w-=check;
                    edge[i^1].w+=check;
                    if(low==0) break;
                }
            }
        }
        return diss;
    }
    inline int max_flow(){
        int ans=0;
        while(spfa()){
            b[t]=1;
            while(b[t]){
                memset(b,0,sizeof(b));
                ans+=dfs(s,inf);
            }
        }
    }
    inline bool cmp(len x,len y)
    {
        if(x.l<y.l) return 1;
        else if(x.l==y.l&&x.r<y.r) return 1;
        return 0;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read();k=read();
        s=0;t=n+n+2;
        S=n+n+1;
        add(s,S,k,0);
        for(re int i=1;i<=n;i++){
            a[i].l=read();a[i].r=read();
            if(a[i].l>a[i].r) swap(a[i].l,a[i].r);
        }
        sort(a+1,a+n+1,cmp);
        for(re int i=1;i<n;i++)
         for(re int j=i+1;j<=n;j++)
          if(a[i].r<=a[j].l) add(i+n,j,1,0);
        for(re int i=1;i<=n;i++){
            add(S,i,1,0);add(i+n,t,1,0);add(i,i+n,1,-a[i].r+a[i].l);
        }
        max_flow();
        cout<<-tot;
    }
     
  • 相关阅读:
    React Native-安卓环境的搭建
    python爬虫学习之日志记录模块
    Python爬虫学习之正则表达式爬取个人博客
    eclipse运行spark程序时日志颜色为黑色的解决办法
    python爬虫学习之爬取全国各省市县级城市邮政编码
    python 字典详细使用
    python爬虫学习之查询IP地址对应的归属地
    python jieba库的基本使用
    Eclipse环境搭建并且运行wordcount程序
    Hadoop2.0伪分布式平台环境搭建
  • 原文地址:https://www.cnblogs.com/victorique/p/8682350.html
Copyright © 2020-2023  润新知