poj_1716 Integer Intervals(差分约束系统+SPFA)

来源:互联网 发布:铜镀铬和不锈钢 知乎 编辑:程序博客网 时间:2024/06/11 23:11
Integer Intervals
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 14247 Accepted: 6059

Description

An integer interval [a,b], a < b, is a set of all consecutive integers beginning with a and ending with b.
Write a program that: finds the minimal number of elements in a set containing at least two different integers from each interval.

Input

The first line of the input contains the number of intervals n, 1 <= n <= 10000. Each of the following n lines contains two integers a, b separated by a single space, 0 <= a < b <= 10000. They are the beginning and the end of an interval.

Output

Output the minimal number of elements in a set containing at least two different integers from each interval.

Sample Input

43 62 40 24 7

Sample Output

4
求最小的元素集合使得题目所给的每个区间中至少有2个元素。
---------------------------
差分约束系统,即一个不等式组,每个不等式形如 xj-xi<=bk,bk是已知常数。
这些不等式有点像最短路中的不等式 d[v]<=d[u]+w(u,v)。
所以可以考虑对于每个约束条件 xj-xi<=bk,新建一条边i->j,权值为bk。
然后模拟一个总源点s与其他点相连,权值为0,则从s出发到其他顶点i的最短路即为xi的值
(用SFPA求最短路时可以先将所有顶点入队,这就相当于从总源点s出发)。
可以发现此时得到的值是xi的最大值(因为一开始初始化dis[i]=inf,松弛操作,dis[i]不断减小,直到满足题意)。
---------------------------
这道题我们设S[i]为从0到i所有元素个数。
则在区间[a, b]中有 S[b] - S[a-1] >=2。
同时可以发现,0 <= S[i] - S[i-1] <=1
可化为:S[i] - S[i-1]  >= 0,S[i-1] - S[i] >= -1
这样我们就得到了一组不等式。
题目要求最小解,所以要求最长路,因为求最长路时一开始初始化dis[i]=0,松弛操作,dis[i]不断增加,直到满足题意后不再增加。
---------------------------
一开始用向前星因为数组范围RE了,用向前星虽然方便,但注意数组大小。
//向前星#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 10010#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;struct Edge{    int b, c, next;}edge[3000010];int head[maxn], dis[maxn], cot;bool vis[maxn];int n, m, s, e;void SPFA(int s){    memset(vis, 0, sizeof(vis));    queue<int> Q;    for(int i = s; i <= e; i++)    {        Q.push(i), vis[i] = 1, dis[i] = 0;    }    while(!Q.empty())    {        int a = Q.front();        Q.pop(), vis[a] = false;        for(int i = head[a]; i != -1; i = edge[i].next)        {            int b = edge[i].b;            if(dis[b] < dis[a] + edge[i].c)            {                dis[b] = dis[a] + edge[i].c;                if(!vis[b])                {                    Q.push(b), vis[b] = true;                }            }        }    }}void Add_edge(int a, int b, int c){    edge[cot].b = b, edge[cot].c = c, edge[cot].next = head[a], head[a] = cot++;}int main(){    while(~scanf("%d", &m))    {        cot = 0, s = inf, e = 0;        memset(head, -1, sizeof(head));        int a, b;        for(int i = 1; i <= m; i++)        {            scanf("%d%d", &a, &b);            Add_edge(a, b+1, 2);            s = min(s, a), e = max(e, b+1);        }        for(int i = s; i < e; i++)        {            Add_edge(i, i+1, 0);            Add_edge(i+1, i, -1);        }        SPFA(s);        printf("%d\n", dis[e]);    }    return 0;}


//vector#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 10010#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;struct Edge{    int from, to, dist;    Edge(int u, int v, int c) : from(u), to(v), dist(c){}};int n, m, s, e;struct BellmanFord{    int n, m;    vector<Edge> edges;    vector<int> G[maxn];    bool inq[maxn]; //是否在队列中    int d[maxn]; //s到各个点的距离    //int p[maxn]; //最短路中的上一条弧    //int cnt[maxn]; //进队次数    void init(int n)    {        this->n = n;        for(int i = 0; i <= n; i++) G[i].clear();        edges.clear();    }    void AddEdge(int from, int to, int dist)    {        edges.push_back(Edge(from, to, dist));        m = edges.size();        G[from].push_back(m-1);    }    int bellman_ford(int s)    {        queue<int> Q;        memset(inq, 0, sizeof(inq));        //memset(cnt, 0, sizeof(cnt));        for(int i = s; i <= e; i++)        {            Q.push(i), d[i] = 0, inq[s] = 1;        }        while(!Q.empty())        {            int u = Q.front(); Q.pop();            inq[u] = false;            for(int i = 0; i < G[u].size(); i++)            {                Edge& e = edges[G[u][i]];                if(d[e.to] < d[u] + e.dist)                {                    d[e.to] = d[u] + e.dist;                    //p[e.to] = G[u][i];                    if(!inq[e.to])                    {                        Q.push(e.to), inq[e.to] = true;                        //if(++cnt[e.to] > n) return false;                    }                }            }        }        return d[e];    }};BellmanFord bf;int A[maxn], B[maxn];int main(){    while(~scanf("%d", &m))    {        s = inf, e = 0;        int a, b;        for(int i = 1; i <= m; i++)        {            scanf("%d%d", &a, &b);            A[i] = a, B[i] = b+1;            s = min(s, a), e = max(e, b+1);        }        bf.init(e);        for(int i = 1; i <= m; i++) bf.AddEdge(A[i], B[i], 2);        for(int i = s; i < e; i++)        {            bf.AddEdge(i, i+1, 0);            bf.AddEdge(i+1, i, -1);        }        printf("%d\n", bf.bellman_ford(s));    }    return 0;}


0 0
原创粉丝点击