您的位置:首页 > 其它

pku 1201 Intervals(差分约束系统)

2009-08-23 12:09 302 查看
线性规划和图论最短路径的完美转换。

设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;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  intervals struct ini c