zoukankan      html  css  js  c++  java
  • Poj 1201 Intervals

    题目链接:http://poj.org/problem?id=1201

    差分约束系统。

    我们用s[i]代表从[0,i]所含有的元素和

    在本题中,如果[a,b]中有c个元素,那么:

    s[b]-s[a-1]>=c,我们可以推得:s[a-1] - s[b] <= -c

    同时,由于每一个值上最多只能含有一个元素,那么:

    s[i] - s[i-1]<=1 

    s[i] - s[i-1]>=0 推得:s[i-1] - s[i] <=0

    这样:我们有了三个约束不等式:

    s[a-1] - s[b] <= -c

    s[i] - s[i-1]<=1 

    s[i-1] - s[i] <=0

    于是:

    假设题目中所有查询的所在区间范围是:[start,end]的话,那么:

    我们只要求出:s[end] -s[start-1] >= M就可以了。

    其中M就是我们要的最小值。

    我们可以整理成我们容易求解的形式:即:s[start-1] - start[end] <= -M

    就是求从end这一点,到start-1这一点的最短路径。

    然后求出的最短路径求相反数就是M了。

    注意题目要求a可以为0,所有都++避免下标为负。Bellmanford会超时,spfa是首选。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    #define Maxn 50005
    #define Maxm 200005
    #define INF 0x3f3f3f3f
    
    int first[Maxn];
    int next[Maxm];
    int total;
    struct Edge
    {
        int a,b;
        int w;
    }edge[Maxm];
    
    int dist[Maxn];
    int vis[Maxn];
    void init()
    {
        total = 0;
        memset(first,-1,sizeof(first));
    }
    void addEdge(int a,int b,int w)
    {
        edge[total].a = a,edge[total].b = b,edge[total].w = w;
        next[total] = first[a];
        first[a] = total++;
    }
    /*
    bool bellmanFord(int start,int pointNum,int m)
    {
        memset(dist,0x3f,sizeof(dist));
        dist[start] = 0;
        for(int i=0;i<pointNum-1;i++)
        {
            for(int j=0;j<m;j++)
            {
                int a = edge[j].a;
                int b = edge[j].b;
                int w = edge[j].w;
                if(dist[a] + w < dist[b]) dist[b] = dist[a] + w;
            }
        }
        for(int i=0;i<m;i++)
        {
            int a = edge[i].a;
            int b = edge[i].b;
            int w = edge[i].w;
            if(dist[a] + w < dist[b]) 
            {
                return false;
            }
        }
        return true;
    }*/
    int cnt[Maxn];
    bool spfa(int s,int n)
    {
        memset(dist,0x3f,sizeof(dist));
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        dist[s] = 0;
        queue<int> q;
        q.push(s);
        vis[s] = 1;
        while(!q.empty())
        {
            int temp = q.front();
            q.pop();
            vis[temp] = 0;
            for(int i=first[temp];i!=-1;i=next[i])
            {
                int a = edge[i].a;
                int b = edge[i].b;
                int w = edge[i].w;
                if(dist[a] + w < dist[b])
                {
                    dist[b] = dist[a] + w;
                    if(!vis[b])
                    {
                        vis[b] = 1;
                        cnt[b]++;
                        if(cnt[b] > n) return false;
                        q.push(b);
                    }
                }
            }
        }
        //判负环
        return true;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif
        int n;
        int a,b,c;
        int start,end;
        while(scanf(" %d",&n)!=EOF)
        {
            init();
            start = INF,end = -INF;
            for(int i=1;i<=n;i++)
            {
                scanf(" %d %d %d",&a,&b,&c);
                a++,b++;
                start = min(start,a);
                end = max(end,b);
                //b-a>=c -> a-b<=-c
                addEdge(b,a-1,-c);
            }
            for(int i=start;i<=end;i++)
            {
                //Si - Si-1 <= 1
                addEdge(i-1,i,1);
                //Si-1 - Si <= 0
                addEdge(i,i-1,0);
            }
            //if(!bellmanFord(end,end-start+2,total)) continue;
            if(!spfa(end,end-start+2)) continue;
            int ans = -dist[start-1];
            printf("%d
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    hdu5714 拍照[2016百度之星复赛C题]
    hdu5715 XOR 游戏 [2016百度之星复赛D题]
    AFO
    BZOJ 3566 概率充电器
    BZOJ 3427 Bytecomputer
    BZOJ 4513 储能表
    BZOJ 3667 Miller_Rabin
    BZOJ 4557 侦察守卫
    BZOJ 3894 文理分科
    SUOI #69 奔跑的Aqua
  • 原文地址:https://www.cnblogs.com/riskyer/p/3278100.html
Copyright © 2011-2022 走看看