• POJ 1201 Intervals[差分约束]


    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    #define N 1000005
    #define INF 999999999
    int head[N], vis[N], queue[N], dis[N], outqueue[N];
    int n, index;
    
    struct Edge
    {
        int v, value, next;
    }edge[N];
    void add_Edge(int u, int v, int val)
    {
        edge[index].next=head[u];
        edge[index].v=v;
        edge[index].value=val;
        head[u]=index++;
    }
    
    void Spfa(int s)
    {
        int iq=0, front=0, i, top;
        memset(vis, 0, sizeof(vis));
        memset(outqueue, 0, sizeof(outqueue));
        for(i=1; i<=n; i++)
            dis[i]=INF;
        dis[s]=0;
        queue[iq++]=s;
        vis[s]=1;
        while(iq!=front)
        {
            top=queue[front];
            front++;
            vis[top]=0;
            outqueue[top]++;
            if(outqueue[top]>n)  return ;
            for(i=head[top]; i!=-1; i=edge[i].next)
            {
                if(dis[top]+edge[i].value<dis[edge[i].v])
                {
                    dis[edge[i].v]=dis[top]+edge[i].value;
                    if(vis[edge[i].v]==0)
                    {
                        vis[edge[i].v]=1;
                        queue[iq++]=edge[i].v;
                    }
                }
            }
        }
    }
    int main()
    {
        int nn, a, b, c, i, maxn;
        while(scanf("%d", &n)!=EOF)
        {
            maxn=0, index=0;
            memset(head, -1, sizeof(head));
            for(i=0; i<n; i++)
            {
                scanf("%d%d%d", &a, &b, &c);
                maxn=max(maxn, b);
                add_Edge(a-1, b, -1*c);
            }
            for(i=1; i<=maxn; i++)
            {
                add_Edge(i, i-1, 1);
                add_Edge(i-1, i, 0);
            }
            n=maxn;
            Spfa(0);
            printf("%d
    ", -1*dis[maxn]);
        }
        return 0;
    }
    View Code

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

    题目大意:有一个集合,给出n个关系,每组关系三个数a, b, c代表[a, b]区间最少c个数。求出集合中做少有多少个数字

    解题思路:[差分约束] 1.我们首先要转化成差分约束的特征形势x-y<=z的形势。

    2.我们设ti表示i之前的区间有多少个数。那么tb-t(a-1)>=c ---(变形)--->t(a-1)-tb<=-c;

    由于ti我们有合理的意义,那么0=<ti-t(i-1)<=1,即相邻两个数区间最多增加1个数 变形得到:ti-t(i-1)<=1  t(i-1)-ti<=0

    3.组合上面的条件,得到差分约束系统。建图

    4.用spfa算法求解最短路

    5.由于t(a-1)-tb<=-c,c加了负号, 因此得出的结果要从负数变为整数

     代码如下:

  • 相关阅读:
    小程序模板template问题记录
    datepicker 组件 的坑
    js实现 throttle 和 debounce
    vuex简单使用
    webpack 打包图片 缺失问题
    invalid prop `current` of type `string` supplied to `pagination`, expected `
    HTML5自定义属性之data-*
    vue组件传值方式介绍
    解决github.com 打不开问题
    git密令使用
  • 原文地址:https://www.cnblogs.com/Hilda/p/3226711.html
Copyright © 2020-2023  润新知