POJ 2983 Is the information reliable?
SPFA+差分约束练习题。
注意事项:
P: //dis[a] - dis[b] = c;
//dis[a] - dis[b] <= c;
//dis[b] - dis[a] <= -c;
V: //dis[a] - dis[b] >= 1;
//dis[b] - dis[a] <= -1;
bellman-ford的话不用加超级源,但是SPFA要,因为给的图可能不连通。
deg表示入队的次数,网上有些代码将deg表示成松弛的次数,提交也过了,但是感觉是不对的(确实也很难构造出这样的数据)。
这是我的代码,可以作为SPFA模板
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using std::memset;
using std::queue;
using std::vector;
const int MAX = 1005;
const int INF = 99999999;
int n,m;
queue<int> q;
struct edge
{
int to,v;
edge(int _to,int _v)
{
to = _to;
v = _v;
}
};
vector<edge> graph[MAX];
bool spfa()
{
int dis[MAX];
int vis[MAX];
int deg[MAX];
for(int i = 0; i < MAX; i++) dis[i] = INF;
memset(vis,0,sizeof(vis));
memset(deg,0,sizeof(deg));
dis[0] = 0;
q.push(0);
deg[0]++;
while(q.empty() == false)
{
int from = q.front();
q.pop();
vis[from] = false;
for(int i = 0 ; i < graph[from].size(); i++)
{
int to = graph[from][i].to;
int v = graph[from][i].v;
if(dis[to] > dis[from] + v)
{
dis[to] = dis[from] + v;
if(!vis[to])
{
q.push(to);
vis[to] = 1;
deg[to]++;
if(deg[to] >= n)
return false;
}
}
}
}
return true;
}
int main()
{
while(scanf("%d%d",&n, &m)!=EOF)
{
//init;
for(int i = 0 ; i < MAX; i++)
{
graph[i].clear();
}
while(!q.empty()) q.pop();
while(m--)
{
char op[2];
scanf("%s", op);
if(op[0] == 'P')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
graph[a].push_back(edge(b,-c));
graph[b].push_back(edge(a,c));
//dis[a] - dis[b] = c;
//dis[a] - dis[b] <= c;
//dis[b] - dis[a] <= -c;
}
else
{
int a,b;
scanf("%d%d",&a,&b);
graph[a].push_back(edge(b,-1));
//dis[a] - dis[b] >= 1;
//dis[b] - dis[a] <= -1;
}
}
//super source;
for(int i = 0 ; i <= n; i++)
{
graph[0].push_back(edge(i,0));
}
if(spfa())
{
printf("Reliable\n");
}
else
{
printf("Unreliable\n");
}
}
}