zoukankan      html  css  js  c++  java
  • poj1201——差分约束,spfa

    poj1201——差分约束,spfa

    Intervals
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 22553   Accepted: 8530

    Description

    You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. 
    Write a program that: 
    reads the number of intervals, their end points and integers c1, ..., cn from the standard input, 
    computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n, 
    writes the answer to the standard output. 

    Input

    The first line of the input contains an integer n (1 <= n <= 50000) -- the number of intervals. The following n lines describe the intervals. The (i+1)-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <= ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.

    Output

    The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.

    Sample Input

    5
    3 7 3
    8 10 3
    6 8 1
    1 3 1
    10 11 1

    Sample Output

    6
    题意:给定N个区间[ai,bi],对应ci,求一个集合,对每个区间都有ci个数在集合中,求集合的数的最小个数
    思路:差分约束,s(bi)-s(ai-1)>=ci,s(i+1)-s(i)>=0,s(i)-s(i+1)>=-1。以区间最左端的Min为源点,求最长路
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    
    const int maxn=50010;
    const int INF=(1<<29);
    
    int N;
    int a,b,c;
    struct Edge
    {
        int v,w;
        Edge *next;
    };Edge e[maxn*10];
    bool vis[maxn];
    int cnt[maxn];
    int dist[maxn];
    int Min,Max;///Min作为源点
    
    void add_edge(int u,int v,int w)
    {
        Edge *pre=&e[u];
        Edge *p=(Edge*)malloc(sizeof(Edge));
        p->v=v;p->w=w;
        p->next=pre->next;
        pre->next=p;
    }
    
    bool relax(int u,int v,int w)
    {
        if(dist[u]+w>dist[v]){
            dist[v]=dist[u]+w;
            return true;
        }
        return false;
    }
    
    bool spfa()
    {
        for(int i=Min;i<=Max+1;i++) dist[i]=-INF;
        dist[Min]=0;
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        queue<int> q;
        q.push(Min);vis[Min]=1;cnt[Min]++;
        while(!q.empty()){
            int u=q.front();q.pop();vis[u]=0;
            for(Edge *p=e[u].next;p!=NULL;p=p->next){
                int v=p->v,w=p->w;
                if(relax(u,v,w)){
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=1;
                        cnt[v]++;
                        if(cnt[v]>N) return false;
                    }
                }
            }
        }
        return true;
    }
    
    int main()
    {
        while(cin>>N){
            memset(e,0,sizeof(e));
            Min=INF;Max=-INF;
            for(int i=0;i<N;i++){
                scanf("%d%d%d",&a,&b,&c);
                add_edge(a,b+1,c);
                if(a<Min) Min=a;
                if(b>Max) Max=b;
            }
            for(int i=Min;i<=Max;i++){
                add_edge(i,i+1,0);
                add_edge(i+1,i,-1);
            }
            spfa();
            cout<<dist[Max+1]<<endl;
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    旧键盘 (20)
    人口普查(20)
    打印沙漏(20)
    程序运行时间(15)
    反转链表 (25)
    科学计数法 (20)
    组个最小数 (20)
    python yield使用
    python如何优雅判断类型
    python中如何优雅使用import
  • 原文地址:https://www.cnblogs.com/--560/p/4412348.html
Copyright © 2011-2022 走看看