poj 图相关之3259 Wormholes
Bellman-Ford算法
196K 79MS
以前单源最短路径只知道Dijkstra算法和Floyed算法,但是Dijkstra算法无法判断含负权边的图的最短路径,而这道题有负权边,所以使用Bellman-Ford算法,Bellman-Ford算法代码的精髓如下(百度百科):
bool Bellman_Ford()
{
for(int i = 1; i <= nodenum; ++i) //初始化
dis[i] = (i == original ? 0 : MAX);
for(int i = 1; i <= nodenum - 1; ++i)
for(int j = 1; j <= edgenum; ++j)
if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cost) //松弛(顺序一定不能反~)
{
dis[edge[j].v] = dis[edge[j].u] + edge[j].cost;
pre[edge[j].v] = edge[j].u;
}
bool flag = 1; //判断是否含有负权回路
for(int i = 1; i <= edgenum; ++i)
if(dis[edge[i].v] > dis[edge[i].u] + edge[i].cost)
{
flag = 0;
break;
}
return flag;
}
这道题的解答:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<memory.h>
#include<vector>
#include<queue>
#include<map>
#define MAXNUM 5500
#define INF 10001
using namespace std;
int F, N, M, W, num, dis[1001];
const int max_w = 10001;
struct Edge
{
int u, v, cost;
}Path[MAXNUM];
bool Bellman_Ford()
{
int i, j, k;
bool flag;
memset(dis, max_w, sizeof(dis));
for (i = 1; i < N; i++)
{
flag = false;
for (j = 0; j < num; j++)
{
if (dis[Path[j].v]>dis[Path[j].u] + Path[j].cost)
{
dis[Path[j].v] = dis[Path[j].u] + Path[j].cost;
flag = true;
}
}
if (!flag)
break;
}
for (i = 0; i < num; i++)
if (dis[Path[i].v]>dis[Path[i].u] + Path[i].cost)
return true;
return false;
}
int main()
{
freopen("1.txt", "r", stdin);
int i, j, k, t, c;
scanf("%d", &F);
while (F > 0)
{
scanf("%d%d%d", &N, &M, &W);//N:nodes M:path W:wormhole
num = 0;
for (i = 0; i < M; i++)
{
scanf("%d%d%d", &k, &t, &c);
Path[num].u = Path[num + 1].v = k;
Path[num].v = Path[num + 1].u = t;
Path[num].cost = Path[num + 1].cost = c;
num += 2;
}
for (i = 0; i < W; i++)
{
scanf("%d%d%d", &k, &t, &c);
Path[num].u = k;
Path[num].v = t;
Path[num++].cost = -c;
}
if (Bellman_Ford())
printf("YES\n");
else
printf("NO\n");
F--;
}
}