• [暑假集训Day2T1]种树


    标算是贪心,我写了个差分约束?????

    设dist[i]表示1-i号土地种的树的总棵数,考虑以下几种约束条件:

    1)dist[y]>=dist[x]+z,即x号土地至y号土地间至少种了z棵树

    2)dist[i-1]>=dist[i]-1,即i号土地最多比i-1号土地多种1棵树

    3)dist[i]>=dist[i-1]+0,即i号土地不会比i-1号土地种的树少

    建图后直接跑单源最长路即可。

    参考代码如下:

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 #include<cstdio>
     5 #define N 30005
     6 #define M 300005
     7 using namespace std;
     8 int v[M],w[M],head[M],nxt[M],dist[M],n,m,cnt,x,y,z,maxn;
     9 bool vis[N];
    10 int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    15     return x*f;
    16 }
    17 void add(int a,int b,int c)
    18 {
    19     v[++cnt]=b;
    20     w[cnt]=c;
    21     nxt[cnt]=head[a];
    22     head[a]=cnt;
    23 }
    24 void spfa(int s)
    25 {
    26     //memset(dist,20,sizeof(dist));
    27     queue<int>q;
    28     dist[s]=0;
    29     q.push(s);
    30     vis[s]=1;
    31     while(!q.empty())
    32     {
    33         int c=q.front();
    34         q.pop();
    35         vis[c]=0;
    36         for(int i=head[c];i;i=nxt[i])
    37         {
    38             int y=v[i];
    39             if(dist[y]<dist[c]+w[i])
    40             {
    41                 dist[y]=dist[c]+w[i];
    42                 if(!vis[y])
    43                 {
    44                     q.push(y);
    45                     vis[y]=1;
    46                 }
    47             }
    48         }
    49     }
    50     //for(int i=1;i<=n;i++)cout<<dist[i]-dist[i-1]<<" ";
    51     //cout<<endl;
    52 }
    53 int main()
    54 {
    55     n=read();m=read();
    56     for(int i=1;i<=m;i++)
    57     {
    58         x=read();y=read();z=read();
    59         maxn=max(maxn,y);
    60         //dist[y]>=dist[x]+z
    61         add(x,y+1,z);
    62     }
    63     for(int i=1;i<=n;i++)
    64     {
    65         //dist[i-1]>=dist[i]-1
    66         //dist[i-1]>=dist[i]-1
    67         add(i,i-1,-1);
    68         //dist[i]>=dist[i-1]+0
    69         add(i-1,i,0);
    70     }
    71     for(int i=1;i<=n;i++)
    72     {
    73         dist[i]=-21374404;
    74         add(0,i,0);
    75     }
    76     spfa(0);
    77     cout<<dist[maxn+1];
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    Linux 中改变主机名的 4 种方法
    如何成为优秀开发人员(一):怎样算是优秀的?
    Java中需要知道的关键字
    Java集合类常见的问题
    如何在 Linux 上复制文件/文件夹到远程系统?
    你还在 Select * 吗?
    技术人解决问题的思路
    如何创建编程语言,以及设计决策中的内容?
    Java内存溢出异常(下)
    如何在 Linux 中查看可用的网络接口
  • 原文地址:https://www.cnblogs.com/szmssf/p/11167676.html
Copyright © 2020-2023  润新知