分析题意:
输入有两种形式:
1:P A B X 即 B + X = A 转化一下: B - A <= -X, A - B <= X 构造边和权:(A, B, -X), (B, A, X)
2:V A B 即 B +1<= A 转化一下:B - A <= -1 构造边和权:(A, B, -1)
WA了无数次,终于过了,不是SPFA的原因,是自己没写好啊!!每次写Bellman_Ford的时候挺简单,写SPFA的时候就死活不过,一度让我怀疑,SPFA是不是不稳定 !!不过还都是因为自己不过小心,处理的时候很容易出错。不过SPFA还是很快的,422ms,Bellman_Ford就跑了2907ms,跟没过也差不多了!
代码
#include<stdio.h>
#include<stdlib.h>
#define INF 0xfffffff
#define NN 1004
#define MM 200004
int edNum, N;
int next[MM];
int root[NN];
int mark[NN];
int cnt[NN];
int dis[NN];
int stack[NN];
struct node{
int e, v;
}edge[MM];
void add(int a, int b, int c){
edge[edNum].e = b;
edge[edNum].v = c;
next[edNum] = root[a];
root[a] = edNum++;
}
int Spfa()
{
int i, top, cur, tmp, nxt;
top = 0;//初始化的时候没有加源点,直接将所有有根的点入栈,也很不错
for (i = 1; i <= N; i++){
dis[i] = INF;
// key1
if (root[i] != -1){
stack[++top] = i;
cnt[i]++;
mark[i] = 1;
}
}
while (top){
cur = stack[top--];
tmp = root[cur];
mark[cur] = 0;
while (tmp != -1){
nxt = edge[tmp].e;
//key2
if (dis[nxt] > dis[cur] + edge[tmp].v){
dis[nxt] = dis[cur] + edge[tmp].v;
if (!mark[nxt]){
cnt[nxt]++;
if (cnt[nxt] > N + 1){
return 1;
}
mark[nxt] = 1;
stack[++top] = nxt;
}
}
tmp = next[tmp];
}
}
return 0;
}
int main()
{
int i, a, b, c, M;
char str[2];
while (scanf("%d%d", &N, &M) != EOF)
{
edNum = 0;
for (i = 0; i <= N; i++){
root[i] = -1;
mark[i] = 0;
cnt[i] = 0;
}
while (M--){
scanf("%s%d%d", str, &a, &b);
if (str[0] == 'P'){
scanf("%d", &c);
add(b, a, c);
add(a, b, -c);
}else{
add(a, b, -1);
}
}
if (Spfa()){
puts("Unreliable");
}else{
puts("Reliable");
}
}
return 0;
}
刚开始写错的两点:
key1:将root[i] != -1 写成 next[i] != -1了
key2:将edge[tmp].v 写成 edge[nxt].v了
太大意了,写的时候要细心啊 !!