读懂题意真难,时间都浪费在理解题意上面了。然后,发现,,这又是一个水题!分分钟撸完了!!!!
引用这里的解释吧我就不多加赘述了!
给你们解释下输入案例数据也许会更清晰的哟!下面看代码,注释很详细!!
若有bug,不足,望悉心指出,thanks!!!!
import java.io.BufferedInputStream;
import java.util.Scanner;
/*
*
输入:
2 //农场个数
3 3 1 //田地 路径 虫洞 分别的个数
1 2 2 //田地路径 起点 终点 权值
1 3 4
2 3 1
3 1 3 //虫洞路径 起点 终点 权值(记得,事实上市负的)
3 2 1 //田地 路径 虫洞 分别的个数
1 2 3 //田地路径 起点 终点 权值
2 3 4
3 1 8 //虫洞路径 起点 终点 权值(记得,事实上市负的)
*
* */
public class POJ3259 {
static int M = 6000, N = 500 + 20, Inf = 1000000000 + 10;
static edge_3295 e[] = new edge_3295[M];
static void start() {
for (int i = 0; i < M; i++) {
e[i] = new edge_3295();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int d[] = new int[N];
start();
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int F = sc.nextInt();
int n, m, w, s, t, l, top;
while (F-- != 0) {//有多少组数据,while 循环读入
//要读入的数据有规律 第一行是 图的节点数 和 边数,但是注意咯 ,这里的边都是可以往返的,所以咯有了下面的
top = 0;
n = sc.nextInt();
m = sc.nextInt();
w = sc.nextInt();
for (int i = 0; i < m; i++) {
s = sc.nextInt();
t = sc.nextInt();
l = sc.nextInt();
e[top++].set(s, t, l);//注意咯上面说的下面 是这里
e[top++].set(t, s, l);//这里对 s 和 t or t和s 进行了两次保存,就是因为线路是可以反向的
}
for (int i = 0; i < w; i++) {
s = sc.nextInt();
t = sc.nextInt();
l = sc.nextInt();
e[top++].set(s, t, -l);
}
if (Bellman_Ford(n, top, d, 0, e)) {
System.out.println("NO");
} else {
System.out.println("YES");
}
}
}
private static boolean Bellman_Ford(int n, int m, int[] d, int s, edge_3295[] e) {//Bellman_Ford 核心代码,模板,这里我就不多解释了
// TODO Auto-generated method stub
for (int i = 0; i <= n; i++) {
d[i] = Inf;
}
d[s] = 0;
int check;
for (int i = 0; i < n - 1; i++) {
check = 0;
for (int j = 0; j < m; j++) {
if (d[e[j].t] > d[e[j].s] + e[j].l) {
d[e[j].t] = d[e[j].s] + e[j].l;
check=1;
}
}
if (check == 0) {
break;
}
}
for (int i = 0; i < m; i++) {
if (d[e[i].t] > d[e[i].s] + e[i].l) {
return false;
}
}
return true;
}
}
class edge_3295 {
int s;
int t;
int l;
public void set(int _s, int _t, int _l) {
this.s = _s;
this.t = _t;
this.l = _l;
}
}
样例的输出为:
NO
YES