您的位置:首页 > 其它

POJ 3259 Wormholes(判断负环&(Bellman-Ford|SPFA))

2016-01-15 20:29 603 查看
题目链接:kuangbin带你飞 专题四 最短路练习 F - Wormholes

题意

农场主拥有很多农场,在这些农场之间有很多条路,以及单向的虫洞,每条路走完会花费一定的时间,而冲动可以回到之前的时间,问农场主是否可以通过特定的路径看到出发前的自己?(也就是回到自己出发时间前的出发点)

思路

将农场看做点,路和虫洞看做边,那么显然虫洞是负权边,这样题目就转化为求给定图中是否有负环的问题了。

Bellman-Ford和SPFA都可以进行负环的判断,因为这两个算法以前都没用过,索性就都写了一下,慢慢熟练。

SPFA是对Bellman-Ford进行队列优化的改进版,但提交后反而比Bellman-Ford慢,这点挺奇怪的。

不知道是数据的原因,还是什么?

代码

Bellman-Ford

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N = 509;
const int MAX = 0x3f3f3f3f;
struct Edge
{
int u, v, r;
}edge[N*N+200];

int d
;

bool Bellman_Ford(int n, int e, int src)
{
for(int i=1; i<=n; i++)
d[i] = MAX;
d[src] = 0;

while(d[src] >= 0)
{
bool flag = true;
for(int i=0; i<e; i++)
{
int u = edge[i].u;
int v = edge[i].v;
int to = d[u] + edge[i].r;
if(d[v] > to)
{
d[v] = to;
flag = false;
}
}
if(flag)
return d[src] < 0;
}
return 1;
}

int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n, m, w;
scanf("%d%d%d", &n, &m, &w);
for(int i=0; i<m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[i].u = a;
edge[i].v = b;
edge[i].r = c;
edge[i+m].u = b;
edge[i+m].v = a;
edge[i+m].r = c;
}
for(int i=0; i<w; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[2*m+i].u = a;
edge[2*m+i].v = b;
edge[2*m+i].r = -c;
}
if(Bellman_Ford(n, m*2+w, 1))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}


SPFA

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<queue>

using namespace std;

const int N = 509;
const int MAX = 0x3f3f3f3f;
struct Edge
{
int u, v, r, next;
}edge[N*N+200];

int d
;
int h
;
bool vis
;
int cnt
;

bool spfa(int n)
{
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
for(int i=1; i<=n; i++)
d[i] = MAX;
d[1] = 0;
vis[1] = 1;
cnt[1]++;
queue<int> q;
q.push(1);
while(!q.empty())
{
int x = q.front();
vis[x] = 0;
q.pop();
for(int i = h[x]; i!=-1; i = edge[i].next)
{
int v = edge[i].v;
int to = edge[i].r + d[edge[i].u];
if(d[v] > to)
{
d[v] = to;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
if(++cnt[v] > n)
return 1;
}
}
}
}
return 0;
}

int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n, m, w;
memset(h, -1, sizeof(h));
scanf("%d%d%d", &n, &m, &w);
for(int i=0; i<m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[i].next = h[a];
edge[i].u = a;
edge[i].v = b;
edge[i].r = c;
h[a] = i;
edge[i+m].next = h[b];
edge[i+m].u = b;
edge[i+m].v = a;
edge[i+m].r = c;
h[b] = i+m;
}
for(int i=0; i<w; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[2*m+i].next = h[a];
edge[2*m+i].u = a;
edge[2*m+i].v = b;
edge[2*m+i].r = -c;
h[a] = 2*m+i;
}
if(spfa(n))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: