[POJ1201]Intervals
题目大意:
给数轴上一些整点做标记。
告诉你n条信息,表示[a,b]中有c个做了标记,问至少有几个数被做了标记。
思路:
给a-1到b连一条权值为c的边,给所有的i-1到i连一条权值为0的边,i到i-1连一条权值为-1的边,SPFA跑差分约束即可。
1 #include<queue> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 #include<cstring> 6 inline int getint() { 7 register char ch; 8 while(!isdigit(ch=getchar())); 9 register int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return x; 12 } 13 const int N=50001; 14 struct Edge { 15 int to,w; 16 }; 17 std::vector<Edge> e[N]; 18 inline void add_edge(const int &u,const int &v,const int &w) { 19 e[u].push_back((Edge){v,w}); 20 } 21 std::queue<int> q; 22 bool inq[N]; 23 int dis[N]; 24 int main() { 25 const int n=getint(); 26 int m=0; 27 for(register int i=0;i<n;i++) { 28 const int a=getint(),b=getint(),c=getint(); 29 add_edge(a-1,b,c); 30 m=std::max(m,b); 31 } 32 for(register int i=1;i<=m;i++) { 33 add_edge(i-1,i,0); 34 add_edge(i,i-1,-1); 35 } 36 q.push(0); 37 inq[0]=true; 38 for(register int i=1;i<=m;i++) dis[i]=-1; 39 while(!q.empty()) { 40 const int x=q.front(); 41 q.pop(); 42 inq[x]=false; 43 for(unsigned i=0;i<e[x].size();i++) { 44 const int &y=e[x][i].to,&w=e[x][i].w; 45 if(dis[x]+w>dis[y]) { 46 dis[y]=dis[x]+w; 47 if(!inq[y]) { 48 q.push(y); 49 inq[y]=true; 50 } 51 } 52 } 53 } 54 printf("%d\n",dis[m]); 55 return 0; 56 }