同POJ 1021,建立差分约束系统,只不过此题要求检查负环。
- 建图时精确信息的等号可以化为两个不等式。
- 利用并查集检查负环。
#include<cstdio>
#include<cstring>
using namespace std;
#define maxN 1005
#define INF 0x7F7F7F7F
#define maxE 200005
int nodeNum,edgeNum;
struct edge
{
short px,py;
int w;
}edges[maxE];
int str2num()
{
int num = 0;
char c;
while((c = getchar())&&(c != ' ')&&(c != '\n')&&(c >= 0))
{
num *= 10;
num += c-'0';
}
return num;
}
bool bellman_ford()
{
int i,j,w;
int dis[maxN];
int fa[maxN];
char IsRelax;
int y,x;
memset(dis,0,sizeof(dis));
for(i = 1;i <= nodeNum;i++)
fa[i] = i;
for(i = 0;i < nodeNum-1;i++)
{
IsRelax = false;
for(j = 0;j < edgeNum;j++)
{
x = edges[j].px;
y = edges[j].py;
w = edges[j].w;
if(dis[y] > dis[x]+w)
{
if(fa[x] == y) return true;<span style="white-space:pre"> </span>//并查集检查负环
fa[y] = fa[x];
dis[y] = dis[x]+w;
IsRelax = true;
}
}
if(!IsRelax) return false;
}
for(j = 0;j < edgeNum;j++)
{
x = edges[j].px;
y = edges[j].py;
w = edges[j].w;
if(dis[y] > dis[x]+w)
{
return true;
}
}
return false;
}
int main()
{
int i;
int messageNum;
int a,b,dis;
char c;
while(~scanf("%d%d",&nodeNum,&messageNum))
{
getchar();
edgeNum = 0;
for(i = 0;i < messageNum;i++)
{
c = getchar();
getchar();
a = str2num();
b = str2num();
if(c == 'P')
{
dis = str2num();
edges[edgeNum].px = a;
edges[edgeNum].py = b;
edges[edgeNum++].w = -1*dis;
edges[edgeNum].px = b;
edges[edgeNum].py = a;
edges[edgeNum++].w = dis;
}
else
{
edges[edgeNum].px = a;
edges[edgeNum].py = b;
edges[edgeNum++].w = -1;
}
}
if(bellman_ford()) printf("Unreliable\n");
else printf("Reliable\n");
}
return 0;
}

本文介绍了一种使用并查集结合Bellman-Ford算法来检测图中是否存在负环的方法。通过处理输入信息转化为边集合,并利用Bellman-Ford算法进行松弛操作判断负环的存在性。
2730

被折叠的 条评论
为什么被折叠?



