POJ 1201 Intervals

来源:互联网 发布:centos启动mysql服务 编辑:程序博客网 时间:2024/05/19 03:17

Intervals

差分约束题目。首先建图,我们采用num[n]表示[0 , n]区间的点的个数。然后这题我们就能很容易给出方程即:num[x] - num[y-1] >= c;转化为: num[x] - c >= num[y-1] ,这样我们就可以建立出对应的图了。但是这个图还不完整,因为还有些隐藏的条件没被发掘出来,我们需要进一步的挖掘。对于区间[i , i] 的点的个数肯定是大于等于0,小于等于1,对应的方程就是:num[i+1] - num[i]>=0&& num[i+1]-num[i]<=1,这样我们就可以将图完全化了。但是我们发现这样会有150000多条边,然后又50000个点,这样用bellman会超时。因为这个题目必定有解,可以这样考虑下,如果当所有的边都不会对其中的点进行优化的时候,那么就到达稳定状态,这样我们就可以将bellman算法算法外重循环更改一下做个判断:如果没有松弛操作的话,我们就直接退出循环。时间:375ms代码如下:

#include<stdio.h>#include<string.h>#define MAXN 50005int n ;int m ;int nmax ;struct Node{int s ;int e ;int w ;}edge[MAXN * 3];int num[MAXN] ;int len ;void read(){scanf("%d" , &n) ;int i ;int p ;int q ;int w ;len = 0 ;nmax = 0 ;memset(num , 0 , sizeof(num)) ;for(i = 0 ; i < n ; i ++){scanf("%d %d %d" , &p , &q , &w) ;if(nmax < p)nmax = p ;if(nmax < q)nmax = q ;if(p == 0){num[q] = w ;continue ;}edge[len].e = p - 1 ;edge[len].s = q ;edge[len].w = -w ;len ++ ;}nmax = nmax ;for(i = 0 ; i < nmax - 1 ; i ++){edge[len].s = i ;edge[len].e = i + 1 ;edge[len].w = 1 ;len ++ ;}for(i = 0 ; i < nmax - 1 ; i ++){edge[len].s = i + 1 ;edge[len].e = i ;edge[len].w = 0 ;len ++ ;}}void bellman(){bool flag = true ;while(flag){flag = false ;for(int j = 0 ; j < len ; j ++){if(num[edge[j].e] > num[edge[j].s] + edge[j].w){num[edge[j].e] = num[edge[j].s] + edge[j].w ;flag = true ;}}}}int main(){read() ;bellman() ;printf("%d\n" , num[nmax] - num[0]) ;return 0 ;}


原创粉丝点击