题意:
两题很像,一个是判断负环是否存在(558),一个是判断正环是否存在(125)
思路:
用floyd,如果形如f[i][i]是正数则有正环,如果是负数,则有负环
注:
558这题用floyd不好,用时太长了,一般用bell-floyd
代码:
uva558:floyd:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 2005;
const int inf = 0x3f3f3f3f;
int f,s;
int a, b, c;
int mmap[maxn][maxn];
bool bell() {
for(int k=0; k<f; k++)
for(int i=0; i<f; i++)
for(int j=0; j<f; j++) {
if(mmap[i][k]!=inf && mmap[k][j]!=inf && mmap[i][j]>(mmap[i][k]+mmap[k][j])) {
mmap[i][j] = mmap[i][k]+mmap[k][j];
if(mmap[i][j]<0 &&i==j) return true;
}
}
return false;
}
int main() {
int cas;
scanf("%d", &cas);
while(cas--) {
scanf("%d%d", &f, &s);
memset(mmap, inf, sizeof(mmap));
for(int i=0; i<s; i++) {
scanf("%d%d%d", &a, &b, &c);
mmap[a][b] = c;
}
if(bell()) printf("possible\n");
else printf("not possible\n");
}
return 0;
}
bell:
#include<cstdio>
const int maxn = 2005;
const int INF = 0x3f3f3f3f;
int x[maxn], y[maxn], w[maxn];
int d[1005];
int n, m;
bool bell() {
for(int i=0; i<n; i++)
d[i] = INF;
d[0] = 0;
for(int k=0; k<n-1; k++)
for(int i=0; i<m; i++) {
int a = x[i], b = y[i];
if(d[b] > d[a]+w[i] && d[a] != INF) {
d[b] = d[a] + w[i];
}
}
for(int i=0; i<m; i++) {
if(d[x[i]] != INF && d[y[i]] > d[x[i]]+w[i])//最短路越来越小
return true;
}
return false;
}
int main() {
int kase;
scanf("%d", &kase) ;
while(kase--) {
scanf("%d%d", &n, &m);
for(int i=0; i<m; i++) {
scanf("%d%d%d", &x[i], &y[i], &w[i]);
}
if(bell()) printf("possible\n");
else printf("not possible\n");
}
return 0;
}
uva125:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 35;
const int inf = 0x3f3f3f3f;
int f[maxn][maxn];
int n;
int flag;
void floyd() {
for(int k=0; k<=flag; k++)
for(int i=0; i<=flag; i++)
for(int j=0; j<=flag; j++) {
if(f[i][k] && f[k][j]) f[i][j] += f[i][k]*f[k][j];
}
for(int k=0; k<=flag; k++)
for(int i=0; i<=flag; i++)
for(int j=0; j<=flag; j++) {
if(f[k][k] && f[i][k] && f[k][j]) {
f[i][j] = -1;
}
}
}
int main() {
int a, b;
int cas = 0;
while(scanf("%d", &n) != EOF) {
flag = 0;
memset(f, 0, sizeof(f));
for(int i=0; i<n; i++) {
scanf("%d%d", &a, &b);
f[a][b] = 1;
flag = max(flag, max(a, b));
}
floyd();
printf("matrix for city %d\n", cas++);
for(int i=0; i<=flag; i++) {
printf("%d", f[i][0]);
for(int j=1; j<=flag; j++) {
printf(" %d", f[i][j]);
}
printf("\n");
}
}
return 0;
}