POJ 1364
这是一道差分约束系统的题目。所给的约束条件是对于一个序列的子序列来说,子序列的和大于或小于一个数,问是否存在一个序列,使得所有约束条件全部成立。
我采用用数列中类似于数列求和的方式,比如序列a1,a2,a3....令s1=a1,s2=a1+a2,s3=a1+a2+a3...为了方便,我还引入了s0=0,这样就可以根据题目的条件列出不等式,再把不等式转化为求最短路的问题。开始我想当然地认为si>=si-1(i和i-1为下标),加了这个条件之后当然是错的,后来发现了这个问题,将其去掉,但是却忽略了一点:这道题其实是让我判断是否存在负环。因为图可能不连通,所以应该每个点都要作为一次起点,用SPFA求最短路,发现负环则跳出。
总之,大体思路的方向是对的,仍然是细节需要注意。
#include<stdio.h> #include<string.h> #define INF 100000000 #define MAX_VERTEX 110 #define MAX_QUE 100000 int graphic[MAX_VERTEX][MAX_VERTEX]; int dist[MAX_VERTEX]; int spfa(int,int,int); inline void ini(int); int main() { int n,m; while(scanf("%d",&n)!=EOF&&n!=0) { getchar(); scanf("%d",&m); ini(n+1); int i=0; for(i=0;i<m;i++) { int stt,toEnd,delta; char ope[3]; scanf("%d%d%s%d",&stt,&toEnd,ope,&delta); if(ope[0]=='l') { graphic[stt-1][stt+toEnd]=delta-1; } else { graphic[stt+toEnd][stt-1]=-1-delta; } } int flag=1; for(i=0;i<n;i++) { flag=spfa(i,n,n+1); if(flag==0) break; } if(flag) { printf("lamentable kingdom\n"); } else { printf("successful conspiracy\n"); } } return 0; } int spfa(int stt,int end,int lmt) { int front=0,rear=1,que_num; int que[MAX_QUE],in_or_not[MAX_VERTEX],inque_times[MAX_VERTEX]; int i=0; for(i=0;i<lmt;i++) dist[i]=INF; memset(in_or_not,0,sizeof(in_or_not)); memset(inque_times,0,sizeof(inque_times)); que[front]=stt; que_num=1; in_or_not[stt]=1; dist[stt]=0; inque_times[stt]=1; while(que_num!=0) { int now_where=que[front]; in_or_not[now_where]=0; que_num--; int i; for(i=0;i<lmt;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]>lmt) return 0; que[rear]=i; if(rear+1==MAX_QUE) rear=0; else rear++; que_num++; } } } if(front+1==MAX_QUE) front=0; else front++; } return 1; } inline void ini(int lmt) { int i,j; for(i=0;i<lmt;i++) { for(j=0;j<lmt;j++) { graphic[i][j]=INF; } } }