/* *State: POJ1364 Accepted 176K 0MS C++ *题目大意; * 已知一个序列a[1], a[2], ......, a[n],给出它的若干子序列以及对该子序列的 * 约束条件,例如a[si], a[si+1], a[si+2], ......, a[si+ni],且a[si]+a[si+1] * +a[si+2]+......+a[si+ni] < or > ki。求是否存在满足以上m个要求的数列。是 * 则输出“lamentable kingdom”,否则输出“successful conspiracy”。 *解题思路: * s[a] + s[a+1] + …… + s[b] < c 可以转化成前n项和sum[b] - sum[a - 1] < c, * 为了能用Bellman_Ford,即将< 转化成 <= ,sum[b] - sum[a - 1] <= c - 1。 * 转化为最长路或者最短路来判断是否有解都可以。 *解题感想; * 注意题目求约束的最大,或者最小时,就要判断此刻要用的是最短路,还是最长路。 */
Bellman_ford:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <queue> #include <map> #include <string> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 105; const int MAXE = 10005; const int inf = 10000; typedef struct _node { int u, v, w; int next; }N; N edge[MAXE]; int head[MAXN], cntEdge; void init() { cntEdge = 0; for(int i = 0; i < MAXN; i++) head[i] = -1; } void addEdge(int u, int v, int w) { edge[cntEdge].u = u; edge[cntEdge].v = v; edge[cntEdge].w = w; edge[cntEdge].next = head[u]; head[u] = cntEdge++; } int Bellman_ford(int s, int n) { int dis[MAXN]; for(int i = 0; i <= n; i++) dis[i] = inf; dis[s] = 0; for(int i = 0; i < n-1; i++) { bool flag = false; for(int j = 0; j < cntEdge; j++) { int u = edge[j].u; int v = edge[j].v; int w = edge[j].w; if(dis[v] > dis[u] + w) { dis[v] = dis[u] + w; flag = true; } } if(!flag) break; } //cout << "-----------------" << endl; //for(int i = 0; i <= n; i++) // cout << dis[i] << " "; //cout << "-----------------" << endl; for(int f = 0; f < cntEdge; f++) { int u = edge[f].u, v = edge[f].v; int w = edge[f].w; if(dis[v] > dis[u] + w) return -1; } return 1; } int main(void) { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int n, m; while(scanf("%d", &n), n) { scanf("%d", &m); int u, v, w; char op[5]; init(); for(int i = 0; i < m; i++) { scanf("%d %d %s %d", &u, &v, op, &w); if(op[0] == 'g') addEdge(u + v + 1, u, -w - 1); else addEdge(u, u + v + 1, w - 1); } for(int i = 1; i <= n + 1; i++) addEdge(0, i, 0); int sol = Bellman_ford(0, n + 2); if(sol == -1) printf("successful conspiracy\n"); else printf("lamentable kingdom\n"); } return 0; }
spfa:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//spfa //State: POJ1364 Accepted 192K 0MS C++ 1759B #include <iostream> #include <queue> #include <map> #include <string> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 105; const int MAXE = 10005; const int inf = 10000; typedef struct _node { int u, v, w; int next; }N; N edge[MAXE]; int head[MAXN], cntEdge; void init() { cntEdge = 0; for(int i = 0; i < MAXN; i++) head[i] = -1; } void addEdge(int u, int v, int w) { edge[cntEdge].u = u; edge[cntEdge].v = v; edge[cntEdge].w = w; edge[cntEdge].next = head[u]; head[u] = cntEdge++; } int spfa(int s, int n) { queue<int> Q; int inQ[MAXN] = {0}, in[MAXN] = {0}; int dis[MAXN]; for(int i = 0; i <= n; i++) dis[i] = inf; Q.push(s); dis[s] = 0; inQ[s] = 1; in[s]++; while(!Q.empty()) { int pre = Q.front(); Q.pop(); inQ[pre] = 0; for(int f = head[pre]; f != -1; f = edge[f].next) { int son = edge[f].v, w = edge[f].w; if(dis[son] > dis[pre] + w) { dis[son] = dis[pre] + w; if(!inQ[son]) { inQ[son] = 1; Q.push(son); in[son]++; if(in[son] > n) return -1; } } } } return 1; } int main(void) { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int n, m; while(scanf("%d", &n), n) { scanf("%d", &m); int u, v, w; char op[5]; init(); for(int i = 0; i < m; i++) { scanf("%d %d %s %d", &u, &v, op, &w); if(op[0] == 'g') addEdge(u + v + 1, u, -w - 1); else addEdge(u, u + v + 1, w - 1); } for(int i = 1; i <= n + 1; i++) addEdge(0, i, 0); int sol = spfa(0, n + 2); if(sol == -1) printf("successful conspiracy\n"); else printf("lamentable kingdom\n"); } return 0; }