poj 1201 Intervals (差分约束)

 1 /*

 2 http://poj.org/problem?id=1201

 3 题目的转换真的非常非常巧妙,让我再来梳理一下。本题的题意是给了我们一些区间,然后告诉每个区间中至少需要取Ci个数。

 4 求出满足n个条件的集合C的最少的元素个数。

 5 用dis[i+1]表示从最小值min 到i所选得最小数

 6 则有 dis[i]-dis[j]<=-W(i,j);

 7 此外还必须加上

 8 1>=dis[i+1]-dis[i]>=0;

 9 这样就构成了完整的差分约束系统

10 */

11 #include<stdio.h>

12 #include<vector>

13 #include<iostream>

14 #include<queue>

15 #include<string.h>

16 using namespace std;

17 const int N=200000;

18 int n;

19 struct node

20 {

21 

22     int y;

23     int w;

24 };

25 vector<node>p[N];

26 queue<int>Q;

27 int vis[N],dis[N],min1,max1;

28 void init()

29 {

30     memset(vis,0,sizeof(vis));

31 

32     for(int i=0;i<=max1+1;i++){dis[i]=999999;}

33     dis[min1]=0;

34     vis[min1]=1;

35 }

36 void insert(int x,int y,int z)

37 {

38     node q;

39     q.y=y;

40     q.w=z;

41     p[x].push_back(q);

42 }

43 void spfa(int x)

44 {

45     init();

46     while(!Q.empty())Q.pop();

47     Q.push(min1);

48     while(!Q.empty())

49     {

50 

51         int k=Q.front();

52         Q.pop();

53         vis[k]=0;//出来之后还可能再进

54 

55         for(int i=0;i<p[k].size();i++)

56         {

57              int   a=p[k][i].y;

58              int len=p[k][i].w;

59             if(dis[a]>dis[k]+len)

60             {

61                 dis[a]=dis[k]+len;

62                 if(!vis[a])

63                 {

64                     vis[a]=1;

65                     Q.push(a);

66                 }

67             }

68         }

69     }

70 

71 

72 }

73 int main()

74 {

75     int i,x,y,z;

76     while(~scanf("%d",&n))

77     {

78         for(i=0;i<=N;i++)p[i].clear();

79         min1=999999;

80         max1=-999999;

81         for(i=0;i<n;i++)

82         {

83             scanf("%d%d%d",&x,&y,&z);

84             insert(x,y+1,-z);

85             if(min1>x)min1=x;

86             if(max1<y+1)max1=y+1;

87         }

88         for(i=min1;i<=max1;i++)

89         {

90             insert(i,i+1,0);

91             insert(i+1,i,1);

92         }

93         spfa(min1);

94 

95         printf("%d\n",-dis[max1+1]);

96 

97     }

98 }

你可能感兴趣的:(差分约束)