题目意思:
flymouse是幼稚园班上的班长,一天老师给小朋友们买了一堆的糖果,由flymouse来分发,在班上,
flymouse和snoopy是死对头,两人势如水火,不能相容,因此fly希望自己分得的糖果数尽量多于
snoopy,而对于其他小朋友而言,则只希望自己得到的糖果不少于班上某某其他人就行了。
比如A小朋友强烈希望自己的糖果数不能少于B小朋友m个,即B- A<=m,A,B分别为
A、B小朋友的分得的糖果数。这样给出若干组这样的条件,要使fly最后分得的糖果数s1和snoopy
最后分得的糖果数s2差别取到最大!即s2-s1取最大.
因此根据题意,可以列出如下的不等式:
Sbi-Sai<=ci(1=<i<=n)
最终要使得Sn-S1最大;
其实就是一个差分约束系统。
求最短路时用到的三角形不等式中,最终对于每条有向边(u,v)有: d[v]<=d[u]+w(u,v);
将Sbi-Sai<=ci变成Sbi<=Sai+ci;就跟上式的形式相似。
在最短路的松弛过程中每次都是 if(d[v]>d[u]+w(u,v)) then d[v]<=d[u]+w(u,v);
则最后不断的松弛,使得对所有边 d[v]<=d[u]+w(u,v);
对于Sbi<=Sai+ci;通过做bellmanford,Sbi通过不断的松弛,由正的无穷不断减小,直到所有的
约束条件都的到满足,所以这时的求出的Sbi是满足约束条件的最大的一组解!!
这样最后的结果就是Sn-S1,初始时将S1设为0,则最后的结果就是Sn的值!
不过直接用bellman-ford复杂度高了点!用队列优化的bellman-ford即spfa可以承受!
CODE:
/*差分约束*/ /*AC代码:469ms*/ #include <iostream> #define MAXN 30005 #define INF 0x7fffffff struct edge { int v,w,next; }E[150005]; int head[MAXN],ecnt; int Stack[MAXN],dis[MAXN]; bool Instack[MAXN]; int N,M,top; void Insert(int u,int v,int w) { E[ecnt].v=v; E[ecnt].w=w; E[ecnt].next=head[u]; head[u]=ecnt++; } void Init() { int i,u,v,w; memset(head,-1,sizeof(head));ecnt=0; for(i=1;i<=M;i++) { scanf("%d%d%d",&u,&v,&w); Insert(u,v,w);//v-u<=w; } } int SPFA() { int i,u,v,w; memset(Instack,false,sizeof(Instack)); for(i=1;i<=N;i++) dis[i]=INF; top=0; Stack[top++]=1; Instack[1]=true; dis[1]=0; while(top) { u=Stack[--top]; Instack[u]=false; for(i=head[u];i!=-1;i=E[i].next) { v=E[i].v;w=E[i].w; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(!Instack[v]) { Stack[top++]=v; Instack[v]=true; } } } } return dis[N]; } int main() { while(scanf("%d%d",&N,&M)!=EOF) { Init(); int ans=SPFA(); printf("%d\n",ans); } return 0; }