SPFA算法之二

//当题目中并没有明确的唯一源点,就需要添加超级源点,它到各顶点都可达,
//因为如果图是非连通的,那么有些顶点将一直得不到检查,
//解决方法就是在初始队列时,把所有的顶点都压入队列里


#include
<iostream> //poj 2983 差分约束系统,使用并查集
#include <queue>
using namespace std;

const int MAX = 500000;
const int INF = 1000000000;
const int N = 2000;

struct Node
{
int v;
int cost;
int next;
};

Node node[MAX];
int cnt[N];
int adj[N];
bool in_q[N];
int d[N];
int size;
int n, m;

void add_edge(int u, int v, int cost)
{
node[size].v
= v;
node[size].cost
= cost;
node[size].next
= adj[u];
adj[u]
= size++;
}

bool spfa()
{
queue
<int> Q;

memset(cnt,
0, sizeof(cnt));
memset(in_q,
false, sizeof(in_q));
for (int i = 0; i <= n; i++)
d[i]
= INF;
d[
0] = 0;
int u,v,w;
in_q[
0] = true;


for(int i=1;i<=n;++i)
Q.push(i);


while (!Q.empty())
{
u
= Q.front();
Q.pop();
in_q[u]
= false;

for (int i = adj[u]; i != -1; i = node[i].next)
{
v
= node[i].v;
w
= node[i].cost;

if (d[v] < d[u]+w)
{
d[v]
= d[u] + w;
if (!in_q[v])
{
in_q[v]
= true;
Q.push(v);

if (++cnt[v] >= n) return false;
}
}
}
}
return true;
}
int main()
{
char c;
int a, b ,w;

while (scanf("%d%d", &n, &m) != EOF)
{
size
= 0;
for (int i = 0; i <= n; i++)
adj[i]
= -1;

for (int i = 0; i < m; i++)
{
getchar();
scanf(
"%c", &c);
if (c == 'P')
{
scanf(
"%d%d%d", &a, &b, &w);
add_edge(b, a, w);
add_edge(a, b,
-w);
}
else if (c == 'V')
{
scanf(
"%d%d", &a, &b);
add_edge(b, a,
1);
}
}
if (spfa())
printf(
"Reliable\n");
else
printf(
"Unreliable\n");
}
return 0;
}

  

posted on 2011-08-24 16:08  sysu_mjc  阅读(162)  评论(0编辑  收藏  举报

导航