pku 1201 Intervals(差分约束系统)

线性规划和图论最短路径的完美转换。

设S(i)表示从0到i-1这i个数中,有多少个数是是被选中的。

对输入 a b c,有S(b+1)-S(a)>=c。(1)

同时有0<=S(i+1)-S(i)<=1。(2)(3)

根据这三个不等式构建图。

 

通常在构图完成后,我们需要求两个节点之间的最短距离。
构图完成后怎么求最短路?
1.把所有的节点的初始dist都设置为0,用bellman-ford跑一遍。
2.想要用spfa的话,就需要把所有的节点的初始dist都设置为0,然后所有节点都加到候选队列(或者栈)中去。(这和设置超级源点是一回事)

 

 

#include <iostream> using namespace std; const int max_n=50005; struct Edge { int to,weight,next; }edges[max_n*4]; int edge_num=0+max_n; void Add_Edge(int from,int to,int weight) { edges[edge_num].to=to; edges[edge_num].weight=weight; edges[edge_num].next=edges[from].next; edges[from].next=edge_num; edge_num++; } int min_num[max_n]; int my_stack[max_n]; bool in_stack[max_n]; void Spfa(int num) { memset(min_num,0,sizeof(min_num)); memset(in_stack,1,sizeof(in_stack)); for(int i=0;i<=num;i++) my_stack[i]=i; int stack_top=num; while(stack_top>=0) { int k=my_stack[stack_top--]; int p=edges[k].next; while(p!=-1) { if(min_num[k]+edges[p].weight<min_num[edges[p].to]) { min_num[edges[p].to]=min_num[k]+edges[p].weight; if(!in_stack[edges[p].to]) { my_stack[++stack_top]=edges[p].to; in_stack[edges[p].to]=true; } } p=edges[p].next; } in_stack[k]=false; } } int main() { int n,max_num=0,a,b,c; memset(edges,-1,sizeof(edges)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d%d",&a,&b,&c); Add_Edge(b+1,a,-c); if(b+1>max_num) max_num=b+1; } for(int i=0;i<max_num;i++) { Add_Edge(i,i+1,1); Add_Edge(i+1,i,0); } Spfa(max_num); printf("%d/n",min_num[max_num]-min_num[0]); return 0; }


 

你可能感兴趣的:(c,struct,ini,Intervals)