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

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

    差分约束裸题;

    设 s[i] 表示到 i 选了数的个数前缀和;

    根据题意,可以建立以下三个限制关系:

    s[bi] >= s[ai-1] + ci ( 1 <= i <= n)

    s[i] >= s[i-1] + 0 ( 1 <= i <= mx)

    s[i-1] >= s[i] + (-1) (1 <= i <= mx)

    然后求最长路,可以发现其中的 dis 值不会多余增大,也就满足题意要求的最小集合条件;

    1A了好开心!

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int const maxn=50005;
    int n,hd[maxn],ct,dis[maxn],mx;
    bool vis[maxn];
    queue<int>q;
    struct N{
        int to,nxt,w;
        N(int t=0,int n=0,int w=0):to(t),nxt(n),w(w) {}
    }ed[maxn*3];
    void add(int x,int y,int z){ed[++ct]=N(y,hd[x],z); hd[x]=ct;}
    void spfa()
    {
        memset(dis,-3,sizeof dis);
        dis[0]=0; vis[0]=1; q.push(0);
        while(q.size())
        {
            int x=q.front(); q.pop(); vis[x]=0;
            for(int i=hd[x];i;i=ed[i].nxt)
            {
                int u=ed[i].to;
                if(dis[u]<dis[x]+ed[i].w)
                {
                    dis[u]=dis[x]+ed[i].w;
                    if(!vis[u])vis[u]=1,q.push(u);
                }
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1,a,b,c;i<=n;i++)
        {
            scanf("%d%d%d",&a,&b,&c); if(a>b)swap(a,b);
            mx=max(mx,max(a,b));
            add(a-1,b,c);
        }
        mx=max(mx,n);
        for(int i=1;i<=mx;i++)//
        {
             add(i-1,i,0); add(i,i-1,-1);
        }
        spfa();
        printf("%d",dis[mx]);
        return 0;
    }
  • 相关阅读:
    Spring学习记录-源码构建
    Spring学习记录
    java相关技术提纲
    Seata 分布式事务框架
    SourceTree学习记录
    其他源码管理工具
    分布式事务
    Score (模拟题)
    大整数排序
    字符串的查找删除 时间限制:1 Seconds 内存限制:32 Mbyte
  • 原文地址:https://www.cnblogs.com/Zinn/p/9278421.html
Copyright © 2011-2022 走看看