pku2983 差分约束系统(SPFA + 栈)

Is the Information Reliable?

分析题意:

输入有两种形式:

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了

太大意了,写的时候要细心啊 !!

你可能感兴趣的:(SPFA)