POJ 1201 Intervals【差分约束】


POJ 1201 Intervals
http://poj.org/problem?id=1201
问题概述:
    提供n组ai,bi,ci,表示在区间[ai,bi]中最少的整数个数,
 求所有提供区间中所包含的最小整数个数
转化:
    用S[i]表示[0,i]区间内的整数个数,则
       1.S[bi+1]-S[ai]>=ci
       2.1>=S[i+1]-S[i]>=0
    求:MIN(S[e]-S[s]);

  思路:从不等式中易想到差分限制系统
  即若a-b>=c,建立从b指向a的边,边的权重为c,
  那么最终问题转化为从s到e的最长路,用SPFA即可

View Code
1 #include<stdio.h>
2 #include<queue>
3  usingnamespace std;
4  constint MAXN =50004;//最多可能出现的点数
5 struct EDGE
6 {
7 int v;//大小
8 int w;//权重
9 EDGE *next;
10 }edges[MAXN*3],*edindex[MAXN];
11 int ednum;//边的数目
12 //添加边
13 inline void addEdge(int a,int b,int c)
14 {
15 EDGE *p =&edges[ednum++];
16 p->v = b;
17 p->w = c;
18 p->next = edindex[a];
19 edindex[a] = p;
20 }
21 inline void swap(int&a,int&b)
22 {
23 int temp = a;a=b;b=temp;
24 }
25
26 int dist[MAXN];
27 bool inQueue[MAXN];//标记当前点十否在队列中
28 void SPFA(int sid,int eid)
29 {
30 int i;
31 for(i=0;i<=eid;i++)
32 {
33 dist[i]=-1;
34 inQueue[i]=false;
35 }
36 queue<int>myQueue;
37 myQueue.push(sid);
38 inQueue[sid]=true;
39 dist[sid]=0;
40 while(!myQueue.empty())
41 {
42 int cur = myQueue.front();
43 myQueue.pop();
44 inQueue[cur]=false;
45 for(EDGE *p = edindex[cur];p;p=p->next)
46 {
47 if(p->w+dist[cur]>dist[p->v])
48 {
49 dist[p->v]=p->w+dist[cur];
50 if(inQueue[p->v]==false)
51 {
52 inQueue[p->v]=true;
53 myQueue.push(p->v);
54 }
55 }
56 }
57 }
58 }
59 int main()
60 {
61 int i,a,b,c,n;;
62 scanf("%d",&n);
63 int right=-1;//记录右结点
64 for(i=0;i<MAXN;i++)
65 edindex[i]=NULL;
66 ednum =0;
67
68 for(i=0;i<n;i++)
69 {
70 scanf("%d%d%d",&a,&b,&c);
71 if(a>b)swap(a,b);
72 b++;
73 right=right>b?right:b;
74 addEdge(a,b,c);
75 }
76
77 for(i=0;i<right;i++)
78 {
79 addEdge(i,i+1,0);
80 addEdge(i+1,i,-1);
81 }
82
83 SPFA(0,right);
84 printf("%d\n",dist[right]);
85 return0;
86 }
posted @ 2011-04-03 20:43  AndreMouche  阅读(852)  评论(0编辑  收藏  举报