• 题解:UVA1723 Intervals


    差分约束裸题

    根据题意建立相应的图

    设s[k]表示0~k中最少取多少个整数,根据题意可知

            s[bi]-s[ai-1]>=ci

    还有一些隐含条件

            s[k]-s[k-1]>=0.    0~k之间选出来的数肯定不必0~k-1少

            s[k]-s[k-1]<=1.    每个数只能被选一次,可变形

    最后求单源最长路

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 const int m=500020;
     8 const int inf=0x3f3f3f3f;
     9 int head[m], dis[m];
    10 bool vis[m];
    11 int maxn, minn;
    12 int T, n;
    13 int cnt;
    14 struct Edge{
    15     int to, w, next;
    16 }e[m*4];
    17 void add(int u,int v,int w){
    18     cnt++;
    19     e[cnt].next=head[u];
    20     e[cnt].w=w;
    21     e[cnt].to=v;
    22     head[u]=cnt;
    23 }
    24 int spfa(int s){
    25     queue<int> q;
    26     int top=0;
    27     for(int i=minn; i<=maxn; i++){
    28         dis[i]=-inf;
    29     }
    30     dis[s]=0;
    31     memset(vis, false, sizeof(vis));
    32     q.push(s);
    33     vis[s]=true;
    34     while(!q.empty()){
    35         int u=q.front();
    36         q.pop();
    37         vis[u]=false;
    38         for(int i=head[u]; i!=-1; i=e[i].next){
    39             int v=e[i].to;
    40             int w=e[i].w;
    41             if(dis[v]<dis[u]+w){
    42                 dis[v]=dis[u]+w;
    43                 if(!vis[v]){
    44                     q.push(v);
    45                     vis[v]=true;
    46                 }
    47             }
    48         }
    49     }
    50     return dis[maxn];
    51 }
    52 int main(){
    53     scanf("%d",&T);
    54     while(T--){
    55         scanf("%d",&n);
    56         int a, b, c;
    57         memset(head,-1,sizeof(head));
    58         minn=inf;
    59         maxn=0;
    60         for(int i=1; i<=n; i++){
    61             scanf("%d%d%d",&a,&b,&c);
    62             add(a-1, b, c);
    63             maxn=max(maxn,b);
    64             minn=min(minn,a-1);
    65         }
    66         for(int i=minn; i<=maxn; i++){
    67             add(i, i+1, 0);
    68             add(i+1, i, -1);
    69         }
    70         int ans=spfa(minn);
    71         printf("%d
    ",ans);
    72         if(T)    printf("
    ");
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    google浏览器切换成中文
    Python 进阶篇
    Linux 命令
    Linux
    Linux
    Linux
    Linux--shell脚本之文本处理工具
    Linux--shell脚本之正则表达式
    Linux
    Linux
  • 原文地址:https://www.cnblogs.com/Aze-qwq/p/9888361.html
Copyright © 2020-2023  润新知