码迷,mamicode.com
首页 > 其他好文 > 详细

poj1201 Intervals——差分约束

时间:2018-07-07 22:28:43      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:pac   eof   include   org   mem   要求   cst   根据   限制   

题目: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;
}

 

poj1201 Intervals——差分约束

标签:pac   eof   include   org   mem   要求   cst   根据   限制   

原文地址:https://www.cnblogs.com/Zinn/p/9278421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!