POJ 3259 Wormholes

同样判断是否存在负环/正环最短路/最长路问题,用SPFA或Bellman-Ford直接求负环就行

C++ Code

这是这次写的SPFA的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#define MAX_NODE 501
#define MAX_EDGE 5402
#define INF 1e9


using namespace std;

int ca, n, m, w;

int head[MAX_NODE];
int cnt;
int dis[MAX_NODE];
bool isInqueue[MAX_NODE];
int num_inqueue[MAX_NODE];

struct edge{
int v;
int cap;
int nex;
}edges[MAX_EDGE];

void add(int s, int t, int cap){
edges[cnt].cap = cap;
edges[cnt].v = t;
edges[cnt].nex = head[s];
head[s] = cnt++;
}

bool spfa(int start){
queue<int> q;
while(!q.empty())
q.pop();
memset(num_inqueue, 0, sizeof(num_inqueue));
memset(isInqueue, false, sizeof(isInqueue));
for(int i = 0; i < MAX_NODE; i++)
dis[i] = INF;
dis[start] = 0;
q.push(start);
isInqueue[start] = true;
while(!q.empty()){
int cur = q.front();
q.pop();
isInqueue[cur] = false;
for(int pos = head[cur]; pos != -1; pos = edges[pos].nex){
int v = edges[pos].v;
if(dis[v] > dis[cur] + edges[pos].cap){
dis[v] = dis[cur] + edges[pos].cap;
if(!isInqueue[v]){
q.push(v);
isInqueue[v] = true;
num_inqueue[v]++;
if(num_inqueue[v] >= n)
return true;
}
}
}
}
return false;
}


int main(){
int from, to, cap;
scanf("%d", &ca);
while(ca--){
cnt = 0;
memset(head, -1, sizeof(head));
scanf("%d%d%d", &n, &m, &w);
for(int i = 0; i < m; i++){
scanf("%d%d%d", &from, &to, &cap);
add(from, to, cap);
add(to, from, cap);
}
for(int i = 0; i < w; i++){
scanf("%d%d%d", &from, &to, &cap);
add(from, to, -cap);
}
bool ans = spfa(1);
if(ans)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}

翻模板的时候发现了几年前写的时候用Bellman-Ford的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f

using namespace std;

struct node
{
int u, v, cap;
}edge[5040];

int cnt;
int dis[520];
int n, m, w;

int Bellman_Ford()
{
int i;
for(i = 1; i <= n; i++)
dis[i] = INF;
dis[1] = 0;
for(i = 1; i <= n; i++)
{
int flag = 0;
for(int j = 0; j < cnt; j++)
{
if(dis[edge[j].v] > dis[edge[j].u] + edge[j].cap)
{
flag = 1;
dis[edge[j].v] = dis[edge[j].u] + edge[j].cap;
}
}
if(flag == 0) break;
}
return (i == n+1);
}

void add(int u, int v, int c)
{
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt++].cap = c;
}

int main()
{
int ca;
scanf("%d", &ca);
while(ca--)
{
scanf("%d%d%d", &n, &m, &w);
cnt = 0;
int a, b, c;
while(m--)
{
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
add(b, a, c);
}
while(w--)
{
scanf("%d%d%d", &a, &b, &c);
add(a, b, -c);
}
int ans = Bellman_Ford();
if(ans == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}