題目連接:http://poj.org/problem?id=1364
題目大意:是否存在一個序列知足給的m組條件
si ni oi ki
若是oi=gt 表示:S(i+ni)-Si>ki
若是oi=lt 表示:S(i+ni)-Si<ki
因爲查分約束的特色要變成x-y<=z的形勢,所以對於上面的式子變形:
oi=gt ---> S(i+ni)-Si<=-ki-1
oi=lt ---> Si-S(i+ni)<=ki-1
而後建圖,用spfa求最短路ios
代碼以下:dom
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 100000 #define M 100000 #define INF 999999999 int dis[N]; //記錄距離 int vis[N]; //標記是否在隊列中 int queue[N]; //模擬隊列 int outqueue[N]; //記錄點i出隊的次數 int head[N]; int index, n; //index記錄head[] s:源點 n個點 struct Edge { int v, next, value; }edge[M]; void add_Edge(int u, int v, int val) { edge[index].next=head[u]; edge[index].v=v; edge[index].value=val; head[u]=index++; } int Spfa(int s) { int iq=0, front=0, i, top; memset(vis, 0, sizeof(vis)); memset(outqueue, 0, sizeof(outqueue)); for(i=0; i<=n; i++) dis[i]=INF; dis[s]=0; queue[iq++]=s; vis[s]=1; while(iq!=front) { top=queue[front]; front++; vis[top]=0; outqueue[top]++; if(outqueue[top]>n) return 0; for(i=head[top]; i!=-1; i=edge[i].next) { if(dis[top]+edge[i].value<dis[edge[i].v]) { dis[edge[i].v]=dis[top]+edge[i].value; if(vis[edge[i].v]==0) { vis[edge[i].v]=1; queue[iq++]=edge[i].v; } } } } return 1; } int main() { int si, ki, i, ni, m; char ch[5]; while(scanf("%d", &n), n) { scanf("%d", &m); index=0; memset(head, -1, sizeof(head)); for(i=0; i<m; i++) { scanf("%d %d %s %d", &si, &ni, ch, &ki); if(ch[0]=='g') add_Edge(ni+si, si-1, -ki-1); else add_Edge(si-1, ni+si, ki-1); } for(i=1; i<=n; ++i) //i=0開始一直wa...wa死我了...淚奔TT... add_Edge(n+1, i, 0); if(Spfa(n+1)) printf("lamentable kingdom\n"); else printf("successful conspiracy\n"); } return 0; }