zoukankan      html  css  js  c++  java
  • 【POJ1201】Intervals-差分约束系统+单源最长路

    测试地址:Intervals
    题目大意:有一个集合,给定n个三元组[ai,bi,ci],表示集合包含区间[ai,bi]中的至少ci个整数,求这个集合最少可能包含的整数个数。
    做法:本题需要用到差分约束系统和单源最长路。
    题目中给了形如bik=aitkci这样的一堆条件,其中tk表示k在不在集合中,如果在,tk=1,否则tk=0。我们可以对t求一个前缀和,令Si=ik=1tk,则上面的条件都可以写成SbiSai1ci的形式了,这就可以用差分约束系统建图了,从一个新建的源点向其他所有点连一条边权为0的边,然后从原点求一遍单源最长路,Smax(bi)的最小值就是它对应顶点的最长路值了,这个值也是要求的答案。如果不明白为什么,建议还是先去了解差分约束系统的定义吧……
    等等,好像有什么东西漏了。注意到ti的取值并不是任意的,它的取值范围是0ti1,也就是说题目还有隐含的条件:0SiSi11,这个条件可以拆成SiSi10Si1Si1两个条件,那么在原来建的图上再添上这些边,求出来的就是正确的答案了。
    有的同学可能会问了,会不会存在无解的情况?可以证明,根据题目的数据范围,建出来的图是不会出现正环的,也就是一定有解,所以不用担心。
    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #define inf 1000000000
    using namespace std;
    int n,maxlen=0,s,first[50010]={0},tot=0;
    int dis[50010];
    bool vis[50010]={0};
    struct edge {int v,d,next;} e[300010];
    queue <int> Q;
    
    void insert(int a,int b,int d)
    {
        e[++tot].v=b;
        e[tot].d=d;
        e[tot].next=first[a];
        first[a]=tot;
    }
    
    void spfa(int s)
    {
        Q.push(s);
        vis[s]=1;dis[s]=0;
        for(int i=0;i<=maxlen+1;i++) dis[i]=-inf;
        while(!Q.empty())
        {
            int v=Q.front();Q.pop();
            for(int i=first[v];i;i=e[i].next)
                if (dis[e[i].v]<dis[v]+e[i].d)
                {
                    dis[e[i].v]=dis[v]+e[i].d;
                    if (!vis[e[i].v]) Q.push(e[i].v);
                }
            vis[v]=0;
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            maxlen=max(maxlen,b);
            insert(a,b+1,c);
        }
    
        s=maxlen+2;
        for(int i=0;i<=maxlen;i++)
        {
            insert(s,i+1,0);
            if (i>0)
            {
                insert(i+1,i,-1);
                insert(i,i+1,0);
            }
        }
    
        spfa(s);
        printf("%d",dis[maxlen+1]);
    
        return 0;
    }
  • 相关阅读:
    成为一名全栈工程师
    【DocFX文档翻译】DocFX 入门 (Getting Started with DocFX)
    SharePoint 2013 项目部署
    dynamics crm跳转到手机版本的页面
    Azure中block和Page的比较 Azure: Did You Know? Block vs Page Blobs
    斐讯k1路由器刷Breed BootLoader(不死UBoot)教程
    DynamicsCRM中的自动保存
    Migrating an ASP.NET MVC application to ADFS authentication
    说一下最近一个月的面试体会吧
    Boss直聘快速导出简历为PDF的方法
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793586.html
Copyright © 2011-2022 走看看