• 【POJ1021】Intervals (最短路解差分约束)


    题目:

    Sample Input

    5
    3 7 3
    8 10 3
    6 8 1
    1 3 1
    10 11 1

    Sample Output

    6

    题意:

      我们选数,每个数只能选一次。给定n个条件[ai,bi]和ci,表示区间[ai,bi]中至少选ci个数,问一共最少选多少个数。

    分析:

      设xi为小于等于i的数中选了多少个数。对于条件[ai,bi]、ci,我们有bi-ai-1>=ci,是差分约束系统,可以用最短路求解。

      另外,题目中有比较隐蔽的条件:每个数只能选一个,一个数选的次数也不能为负,那么就是说对于相邻的两个数x、y,有0<=y-x<=1,要根据这个条件建边才能保证答案无误。

      最后输出Xmx-Xmn。(差分约束系统要不无解,要不有无数解,因为一旦有解只要保证他们之间差值不变即可。题目问一共最少选多少个数,而xi的最小值为0,所以答案为Xmx-Xmn)

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 using namespace std;
     8 #define Maxn 50010
     9 #define INF 0xfffffff
    10 
    11 struct node
    12 {
    13     int x,y,c,next;
    14 }t[Maxn*4];int len=0;
    15 
    16 int first[Maxn],cnt[Maxn],dis[Maxn];
    17 bool bq[Maxn],inq[Maxn];
    18 
    19 int mymin(int x,int y) {return x<y?x:y;}
    20 int mymax(int x,int y) {return x>y?x:y;}
    21 
    22 void ins(int x,int y,int c)
    23 {
    24     t[++len].x=x;t[len].y=y;t[len].c=c;
    25     t[len].next=first[x];first[x]=len;
    26 }
    27 
    28 queue<int > q;
    29 
    30 void spfa(int s)
    31 {
    32     memset(dis,63,sizeof(dis));
    33     memset(inq,0,sizeof(inq));
    34     memset(cnt,0,sizeof(cnt));
    35     if(!q.empty()) q.pop();
    36     dis[s]=0;inq[s]=1;q.push(s);
    37     while(!q.empty())
    38     {
    39         int x=q.front();q.pop();inq[x]=0;
    40         for(int i=first[x];i;i=t[i].next)
    41         {
    42             int y=t[i].y;
    43             if(dis[y]>dis[x]+t[i].c)
    44             {
    45                 dis[y]=dis[x]+t[i].c;
    46                 if(!inq[y])
    47                 {
    48                     q.push(y);
    49                     inq[y]=1;
    50                 }
    51             }
    52         }
    53     }
    54 }
    55 
    56 int main()
    57 {
    58     int m,mx=0,mn=INF;
    59     scanf("%d",&m);
    60     memset(first,0,sizeof(first));
    61     memset(bq,0,sizeof(bq));
    62     for(int i=1;i<=m;i++)
    63     {
    64         int x,y,c;
    65         scanf("%d%d%d",&x,&y,&c);x++;y++;
    66         ins(y,x-1,-c);
    67         bq[x]=bq[y]=1;
    68         mx=mymax(mx,y);mn=mymin(mn,x-1);
    69     }
    70     for(int i=mn;i<mx;i++) ins(i+1,i,0);
    71     for(int i=mn;i<mx;i++) ins(i,i+1,1);
    72     for(int i=mn;i<=mx;i++) ins(mx+1,i,0);
    73     spfa(mx+1);
    74     //for(int i=mn;i<=mx;i++) printf("%d %d
    ",i,dis[i]);
    75     printf("%d
    ",dis[mx]-dis[mn]);
    76     return 0;
    77 }
    [POJ1201]

    感觉自己考虑问题总是不全面啊。

    2016-04-10 16:31:30

  • 相关阅读:
    外贸术语缩写大全简写解释
    免费Shopify主题Dawn
    语音搜索对未来SEO的影响
    基于Prometheus和Grafana监控redis,Oracle,mysql,pg以及sqlserver的方法总结
    使用Grafana 监控 SQLSERVER数据库
    使用influxdb以及Grafana监控vCenter的操作步骤
    Grafana监控Redis的使用情况
    OpenPower服务使用node-exporter prometheus以及grafana进行性能监控的流程
    Mysql localhost 无法登录 root用户的处理过程
    总结: Redis 查看key大小的简单总结
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5374459.html
Copyright © 2020-2023  润新知