zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    网站页面性能优化的 34条黄金守则 (雅虎团队经验)
    进程调度算法小结
    玩转TCP连接
    数据包在网络中的流转
    浅入理解JVM虚拟机
    Leecode no.47 全排列 II
    Leecode no.143 重排链表
    关于我用设计模式对公司代码重构的这件事
    进程间通信方式小结
    Leecode no.82 删除排序链表中的重复元素 II
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5374459.html
Copyright © 2011-2022 走看看