zoukankan      html  css  js  c++  java
  • P1250 种树

    P1250 种树

    题目描述

    一条街的一边有几座房子。因为环保原因居民想要在路边种些树。路边的地区被分割成块,并被编号成1..N。每个部分为一个单位尺寸大小并最多可种一棵树。每个居民想在门前种些树并指定了三个号码B,E,T。这三个数表示该居民想在B和E之间最少种T棵树。当然,B≤E,居民必须记住在指定区不能种多于区域地块数的树,所以T≤E-B+l。居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量。

    写一个程序完成以下工作:

    输入输出格式

    输入格式:

    第一行包含数据N,区域的个数(0<N≤30000);

    第二行包含H,房子的数目(0<H≤5000);

    下面的H行描述居民们的需要:B E T,0<B≤E≤30000,T≤E-B+1。

    输出格式:

    输出文件只有一行写有树的数目

    输入输出样例

    输入样例#1: 
    9
    4
    1 4 2
    4 6 2
    8 9 2
    3 5 2
    输出样例#1: 
    5

    选尽量少的的数,并且符合对每一个区间的要求。

    典型的差分约束,因为是求最小值,所以要用最长路来求,我们设f[i]表示1~i个数中至少选的数的个数,对于每一个区间要求,我们就从B-1向E连一条长度为T的边,表示1~E中选的数的个数至少比1~B-1中选的数的个数多T,也就是B~E中至少选T个数。然而这样是不行的,因为题目中还有隐藏条件,首先十分显然的一个条件f[i+1]>=f[i],因为前i+1个数不可能比前i个数少,所以从i向i+1连一条权值为0的边,其次,对于每个数我们最多只能选一次,所以f[i+1]<=f[i]+1,但是这样不太好,我们移一下项f[i]>=f[i+1]-1,这样我们就要从i+1向i连一条边长为-1的边,最后从一号点跑一遍最长路就好了。

     1 #include<iostream>
     2 #include<string>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<stack>
     7 #include<queue>
     8 #define maxn 100005
     9 using namespace std;
    10 
    11 inline int read()
    12 {
    13     char c=getchar();
    14     int x=1,res=0;
    15     while(c<'0'||c>'9')
    16     {
    17         if(c=='-')
    18         x=-1;
    19         c=getchar();
    20     }
    21     while(c>='0'&&c<='9')
    22     {
    23         res=res*10+(c-'0');
    24         c=getchar();
    25     }
    26     return x*res;
    27 }
    28 
    29 struct edge
    30 {
    31     int next,to,dis;
    32 }g[maxn<<1];
    33 int n,m,aa,bb,cc,num;
    34 int last[maxn],c[maxn],vis[maxn];
    35 queue<int>q;
    36 
    37 void add(int from,int to,int dis)
    38 {
    39     g[++num].next=last[from];
    40     g[num].to=to;
    41     g[num].dis=dis;
    42     last[from]=num;
    43 }
    44 
    45 int main()
    46 {
    47     n=read();m=read();
    48     for(int i=1;i<=m;i++)
    49     {
    50         aa=read();bb=read();cc=read();
    51         add(aa-1,bb,cc);
    52     }
    53     for(int i=0;i<=n;i++)
    54     {
    55         add(i-1,i,0);
    56         add(i,i-1,-1);
    57         c[i]=-100000000;
    58     }
    59     c[0]=0;
    60     q.push(0);
    61     while(q.size())
    62     {
    63         int u=q.front();
    64         q.pop();
    65         vis[u]=0;
    66         for(int i=last[u];i;i=g[i].next)
    67         {
    68             int v=g[i].to;
    69             if(c[v]<c[u]+g[i].dis)
    70             {
    71                 c[v]=c[u]+g[i].dis;
    72                 if(!vis[v])
    73                 {
    74                     vis[v]=1;
    75                     q.push(v);
    76                 }
    77             }
    78         }
    79     }
    80     printf("%d
    ",c[n]);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    微软发布TFS 2018!
    Git小技巧:VIM中如何填写注释信息
    为某金融企业的IT技术部人员提供基于TFS的软件研发流程介绍
    【TFS 2017】使用浏览器上传文件(TFVC)或者编辑代码,错误提示TF14098,需要对文件有PendChange 权限
    TFS 2017 培训
    签入代码(新建分支,新建推拉请求)关联工作项,却找不到自己需要的工作项
    TFS支持移动设备,微软已经走出了第一步(手机上更新、查询工作项)
    在TFS持续集成(持续发布)中执行Telnet任务
    Nginx
    单点登录
  • 原文地址:https://www.cnblogs.com/snowy2002/p/10655026.html
Copyright © 2011-2022 走看看