POJ 2983 Is the Information Reliable? 差分约束
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 14143 | Accepted: 4439 |
Description
The galaxy war between the Empire Draco and the Commonwealth of Zibu broke out 3 years ago. Draco established a line of defense called Grot. Grot is a straight line with N defense stations. Because of the cooperation of the stations, Zibu’s Marine Glory cannot march any further but stay outside the line.
A mystery Information Group X benefits form selling information to both sides of the war. Today you the administrator of Zibu’s Intelligence Department got a piece of information about Grot’s defense stations’ arrangement from Information Group X. Your task is to determine whether the information is reliable.
The information consists of M tips. Each tip is either precise or vague.
Precise tip is in the form of P A B X
, means defense station A is X light-years north of defense station B.
Vague tip is in the form of V A B
, means defense station A is in the north of defense station B, at least 1 light-year, but the precise distance is unknown.
Input
There are several test cases in the input. Each test case starts with two integers N (0 < N ≤ 1000) and M (1 ≤ M ≤ 100000).The next M line each describe a tip, either in precise form or vague form.
Output
Output one line for each test case in the input. Output “Reliable” if It is possible to arrange N defense stations satisfying all the M tips, otherwise output “Unreliable”.
Sample Input
3 4 P 1 2 1 P 2 3 1 V 1 3 P 1 3 1 5 5 V 1 2 V 2 3 V 3 4 V 4 5 V 3 5
Sample Output
Unreliable Reliable
Source
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<sstream> #include<algorithm> #include<queue> #include<deque> #include<iomanip> #include<vector> #include<cmath> #include<map> #include<stack> #include<set> #include<functional> #include<memory> #include<list> #include<string> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f #define sf(x) scanf("%lld",&x) const LL MAXN = 200050; const LL MAXM = 1000050; /* 查分约束系统 节点映射到y坐标系上!ti 为 i到原点的距离 V A B ta - tb>=1 tb - ta <= - 1 P A B X ta - tb >= X tb - ta <= -X 节点性质可得: ti - ti+1 <= 1 spfa 判断有没有负环 + 并查集 判断精确关系是否符合 */ struct edge { LL to, next, dist; }E[MAXM]; LL tot, head[MAXN], dist[MAXN], cnt[MAXN]; LL n, m; bool vis[MAXN]; inline void init() { tot = 0; memset(head, -1, sizeof(head)); } inline void addedge(LL u, LL v, LL d) { E[tot].to = v; E[tot].dist = d; E[tot].next = head[u]; head[u] = tot++; } bool spfa() { memset(vis, false, sizeof(vis)); memset(dist, INF, sizeof(dist)); memset(cnt, 0, sizeof(cnt)); queue<LL> q; q.push(0); vis[0] = true; dist[0] = 0; cnt[0] = 1; while (!q.empty()) { LL f = q.front(); q.pop(); vis[f] = false; for (LL i = head[f]; i != -1; i = E[i].next) { LL v = E[i].to, d = E[i].dist; if (dist[v] > dist[f] + d) { dist[v] = dist[f] + d; if (!vis[v]) { vis[v] = true; q.push(v); if (++cnt[v] > n) return false; } } } } return true; } int main() { while (scanf("%lld%lld", &n, &m) != EOF) { init(); // bool f = false; char op[2]; LL f, t, d; for (LL i = 0; i < m; i++) { scanf("%s", op); if (op[0] == 'P') { sf(f), sf(t), sf(d); addedge(t, f, -d); addedge(f, t, d); } else { sf(f), sf(t); addedge(t, f, -1); } } for (LL i = 1; i <= n; i++) { addedge(0, i, 0); } if (spfa()) cout << "Reliable" << endl; else cout << "Unreliable" << endl; } return 0; }
也可不加附加节点
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<sstream> #include<algorithm> #include<queue> #include<deque> #include<iomanip> #include<vector> #include<cmath> #include<map> #include<stack> #include<set> #include<functional> #include<memory> #include<list> #include<string> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f #define sf(x) scanf("%lld",&x) const LL MAXN = 200050; const LL MAXM = 1000050; /* 查分约束系统 节点映射到y坐标系上!ti 为 i到原点的距离 V A B ta - tb>=1 tb - ta <= - 1 P A B X ta - tb >= X tb - ta <= -X 节点性质可得: ti - ti+1 <= 1 spfa 判断有没有负环 + 并查集 判断精确关系是否符合 */ struct edge { LL to, next, dist; }E[MAXM]; LL tot, head[MAXN], dist[MAXN], cnt[MAXN]; LL n, m; bool vis[MAXN]; inline void init() { tot = 0; memset(head, -1, sizeof(head)); } inline void addedge(LL u, LL v, LL d) { E[tot].to = v; E[tot].dist = d; E[tot].next = head[u]; head[u] = tot++; } bool spfa() { memset(vis, false, sizeof(vis)); memset(dist, INF, sizeof(dist)); memset(cnt, 0, sizeof(cnt)); queue<LL> q; for (int i = 1; i <= n; i++) q.push(i), vis[i] = true, dist[i] = 0; while (!q.empty()) { LL f = q.front(); q.pop(); vis[f] = false; for (LL i = head[f]; i != -1; i = E[i].next) { LL v = E[i].to, d = E[i].dist; if (dist[v] > dist[f] + d) { dist[v] = dist[f] + d; if (!vis[v]) { vis[v] = true; q.push(v); if (++cnt[v] > n) return false; } } } } return true; } int main() { while (scanf("%lld%lld", &n, &m) != EOF) { init(); // bool f = false; char op[2]; LL f, t, d; for (LL i = 0; i < m; i++) { scanf("%s", op); if (op[0] == 'P') { sf(f), sf(t), sf(d); addedge(t, f, -d); addedge(f, t, d); } else { sf(f), sf(t); addedge(t, f, -1); } } /*for (LL i = 1; i <= n; i++) { addedge(0, i, 0); }*/ if (spfa()) cout << "Reliable" << endl; else cout << "Unreliable" << endl; } return 0; }