Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 13804 | Accepted: 4334 |
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
给一段信息,有关于N个点,M条信息。其中每一条信息:
1、P A B X,意思是A站点在B站点北X光年
2、V A B,意思是A站点在B站点北,但不知道确切距离,最少一光年。
对于给出的这段信息,求是否是真是的消息,因为错误的消息有矛盾的信息。
思路:将具体的x,转化成 >= <=,然后直接spfa就好了
spfa代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 1005;
const int maxe = 100005;
const int INF = 1e9;
int k, head[maxn], book[maxn], n, m, cnt[maxn], dis[maxn];
char cmd;
struct node
{
int v, w, next;
}edge[maxe*2];
void addEdge(int u, int v, int w)
{
edge[k].v = v;
edge[k].w = w;
edge[k].next = head[u];
head[u] = k++;
}
void spfa()
{
memset(book, 0, sizeof(book));
memset(cnt, 0, sizeof(cnt));
for(int i = 0; i < maxn; i++) dis[i] = INF;
queue<int> q;
q.push(0);
book[0] = 1;
cnt[0] = 1;
dis[0] = 0;
while(!q.empty())
{
int u = q.front();
q.pop();
book[u] = 0;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int to = edge[i].v, w = edge[i].w;
// cout << to << ' ' << dis[to] << endl;
// cout << dis[to] << ' ' << dis[u]+w <<endl;
if(dis[to] > dis[u] + w)
{
dis[to] = dis[u] + w;
if(!book[to])
{
q.push(to);
if(++cnt[to] > n+1)
{
printf("Unreliable\n");
return ;
}
// cout << cnt[to] << endl;
book[to] = 1;
}
}
}
}
printf("Reliable\n");
return;
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
memset(head, -1, sizeof(head));
k = 1;
int x, y, z;
for(int i = 1; i <= m; i++)
{
scanf(" %c", &cmd);
if(cmd == 'P')
{
scanf("%d%d%d", &y, &x, &z);
addEdge(x, y, z);
addEdge(y, x, -z);
}
if(cmd == 'V')
{
scanf("%d%d", &y, &x);
addEdge(y, x, -1);
}
}
for(int i = 1; i <= n; i++)
addEdge(0, i, 0);
spfa();
}
return 0;
}
Bellman-Ford
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define Infp 0x7fffffff
#define Infn 0x80000000
#define DisCon 1000000000
#define MAX 999999999
#define MIN -999999999
#define Z(a) memset(a, 0, sizeof(a))
#define C(a, b) memcpy(a, b, sizeof(b))
#define Pi acos(-1)
#define FMAX (1E300)
#define FMIN (-1E300)
#define feq(a, b) (fabs((a)-(b))<1E-6)
#define flq(a, b) ((a)<(b)||feq(a, b))
#define RG 1005
struct Edge
{
int b;
int e;
int dis;
}e[200010];//简单的记录边的信息
int bell(int en, int pn)
{
int dis[pn+1];
int chg;
dis[0]=0;
for(int i=1; i<=pn; i++)
dis[i]=DisCon;//这是为了防止溢出才不用最大值
for(int i=0; i<pn; i++)
{
chg=0;
for(int j=0; j<en; j++)
if(dis[e[j].e]>dis[e[j].b]+e[j].dis)//松弛操作
{
dis[e[j].e]=dis[e[j].b]+e[j].dis;
chg=1;//如果最终趋于稳定,就是说肯定没有负权回路了
}
if(!chg)return 1;
/*************解释*****************************
结合《算法导论》的解释,如果从单源出发,而且图是无负权回路的,
那么到任何一个短点的最短路径最多只包含|V|-1条边,而上述代码最
外层的循环次数是|V|次,就是最多将构造含有|V|条边的最短路集合。
假设循环不断进行,一直有最短路被发现(也即一直有松弛的路径更新
),直到i>|V|而退出,这说明这时构造出了一条最短路是有多于|V|条
边的,与初衷矛盾,所以这时说明了图是有负权回路的!
*********************************************/
}
return 0;
}
int main()
{
int N, M;
while(scanf("%d%d", &N, &M)!=EOF)
{
int en=0;
while(M--)
{
getchar();
char c;
scanf("%c", &c);
if(c=='P')//具体的信息,双向的边都要构造
{
int a, b, dis;
scanf("%d%d%d", &a, &b, &dis);
e[en].b=a;
e[en].e=b;
e[en++].dis=dis;
e[en].b=b;
e[en].e=a;
e[en++].dis=-dis;
}
else//模糊的信息,据说边长一定大于1,只构造单向的边
{
int a, b;
scanf("%d%d", &a, &b);
e[en].b=b;
e[en].e=a;
e[en++].dis=-1;
}
}
if(bell(en, N))printf("Reliable\n");
else printf("Unreliable\n");
}
return 0;
}