这是一道差分约束系统的题,刚开始学,还有些地方不是很清楚,靠这道题弄清了一些问题。这道题是是说有一队奶牛要吃饭,有些奶牛互相讨厌,必须至少相隔一定的距离;有些奶牛互相吸引,距离不能大于一个定值。另外,这些奶牛可以处在同一个位置。求这队奶牛最远的长度。
拿题目的数据来说(1,3,10)、(2,4,20)、(2,3,3),很容易得出不等式:x3-x1<=10;x4-x2<=20;x3-x2>=3。并且,由于奶牛顺序不能改变,所以Xi>=Xi-1(i-1是下标)。我们可以把不等式变形为:x2<=x1+5;x3<=x1+10;x2<=x3-20。从而转化为求最短路的问题。这里注意的是,建立的应该是有向图,所以要稍微注意下输入的时候graphic[][]=val两个下标的顺序,开始没注意,所以没有产生正确的结果。
#include<stdio.h> #include<string.h> #define MAX_COWS 1009 #define INF 100000000 #define MAX_QUE 100000 int graphic[MAX_COWS][MAX_COWS]; int spfa(int,int); inline void inic_1div(int,int *); inline void inic_2div(int); int main() { int n,ml,md; while(scanf("%d%d%d",&n,&ml,&md)!=EOF) { inic_2div(n+1); int i=0; for(i=1;i<=n;i++) { graphic[i][i-1]=0; } for(i=0;i<ml;i++) { int cow_a,cow_b,val_ml; scanf("%d%d%d",&cow_a,&cow_b,&val_ml); graphic[ cow_a ][ cow_b ]= val_ml; } for(i=0;i<md;i++) { int cow_a,cow_b,val_md; scanf("%d%d%d",&cow_a,&cow_b,&val_md); graphic[ cow_b ][ cow_a ]=-val_md; } int ans; ans=spfa(1,n); if(ans>=INF) printf("-2\n"); else printf("%d\n",ans); } return 0; } inline void inic_1div(int edge,int dist[]) { int i; for(i=0;i<edge;i++) dist[i]=INF; } inline void inic_2div(int edge) { int i,j; for(i=1;i<edge;i++) { for(j=1;j<edge;j++) { graphic[i][j]=INF; } } } int spfa(int stt,int end) { int que[MAX_QUE],in_or_not[MAX_QUE],dist[MAX_COWS],inque_times[MAX_COWS]; int front=0,rear=1,que_num; inic_1div(end+1,dist); memset(inque_times,0,sizeof(inque_times)); que[front]=stt; dist[stt]=0; que_num=rear-front; in_or_not[stt]=1; while(que_num!=0) { int now_where; now_where=que[front]; in_or_not[que[front]]=0; que_num--; int i; for(i=1;i<=end;i++) { int len=graphic[now_where][i]; if(i!=now_where&&len!=INF&&dist[now_where]+len<dist[i]) { dist[i]=dist[now_where]+len; if(in_or_not[i]==0) { in_or_not[i]=1; inque_times[i]++; if(inque_times[i]>end) return -1;//说明有负环 que[rear]=i; if(rear+1==MAX_QUE) rear=0; else rear++; que_num++; } } } if(front+1==MAX_QUE) front=0; else front++; } return dist[end]; }