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
NO
YES
对于 Sample Input :
farm 1 不能够达到目标。
farm 2 能够,因为 1->2->3->1,他回到1时比原来提前了1秒。
将field作为节点,path作为正权边,wormholes作为负权边,注意:path是双向边。
第一步:添加一个虚拟源点s,并将这个虚拟源点连向所有的节点(field),因此共有N+1个节点,2*M+W+N条边。
第二步:对虚拟源点s运行Bellman-Ford算法,判断是否有源点可达负圈即可。
1 2 3 import java.util.Scanner; 4 5 public class Main { 6 int n; // 节点个数 7 int m; // 边的个数 8 int head[]; // head[i] 表示节点i指向的第一条边的索引是多少 9 int edge[][]; // edge[i]表示第i条边 ,edge[i][1]表示这条边的起点,edge[i][2]表示这条边的终点,edge[i][3]表示这条边的权重 10 int next[]; // next[i]表示第i条边在邻接表中的下一条边是什么 11 int d[]; // d[i]表示第i条边的d值 12 13 int farmNumber; 14 int N[]; 15 int M[]; 16 int W[]; 17 int current_farm = 0; 18 19 public void getSingleFarm(Scanner in){ 20 int current_edge = 0; 21 N[current_farm] = in.nextInt(); 22 M[current_farm] = in.nextInt(); 23 W[current_farm] = in.nextInt(); 24 this.n = N[current_farm]+1; 25 this.m = 2*M[current_farm]+W[current_farm]+N[current_farm]; 26 //2*M+W+N条边 27 head = new int[n]; 28 edge = new int[m][4]; 29 next = new int[m]; 30 d = new int[n]; 31 for(int i=0;i<n;i++){ 32 head[i] = -1; 33 } 34 for(int i=1;i<=N[current_farm];i++){ 35 edge[current_edge][1] = 0; 36 edge[current_edge][2] = i; 37 edge[current_edge][3] = 0; 38 next[current_edge] = head[0]; 39 head[0] = current_edge; 40 current_edge++; 41 } 42 for(int i=1;i<=M[current_farm];i++){ 43 int from = in.nextInt(); 44 int to = in.nextInt(); 45 int cost = in.nextInt(); 46 edge[current_edge][1] = from; 47 edge[current_edge][2] = to; 48 edge[current_edge][3] = cost; 49 next[current_edge] = head[from]; 50 head[from] = current_edge; 51 current_edge++; 52 53 edge[current_edge][1] = to; 54 edge[current_edge][2] = from; 55 edge[current_edge][3] = cost; 56 next[current_edge] = head[to]; 57 head[to] = current_edge; 58 current_edge++; 59 } 60 for(int i=1;i<=W[current_farm];i++){ 61 int from = in.nextInt(); 62 int to = in.nextInt(); 63 int cost = in.nextInt(); 64 edge[current_edge][1] = from; 65 edge[current_edge][2] = to; 66 edge[current_edge][3] = -cost; 67 next[current_edge] = head[from]; 68 head[from] = current_edge; 69 current_edge++; 70 } 71 current_farm++; 72 } 73 public void getInput(Scanner in){ 74 75 farmNumber = in.nextInt(); 76 N = new int[farmNumber]; 77 M = new int[farmNumber]; 78 W = new int[farmNumber]; 79 80 for(int i=1;i<=farmNumber;i++){ 81 getSingleFarm(in); 82 boolean flag = BellmanFord(0); 83 if(flag) System.out.println("NO"); 84 else System.out.println("YES"); 85 86 } 87 } 88 89 public boolean BellmanFord(int s){ 90 for(int i=0;i<n;i++){ 91 d[i] = Integer.MAX_VALUE; 92 } 93 d[s] = 0; 94 boolean flag = true; 95 for(int t=1;t<=n-1;t++){ 96 if(flag){ 97 flag = false; 98 for(int i=0;i<n;i++){ 99 for(int j=head[i];j!=-1;j=next[j]){ 100 if(d[edge[j][2]]>d[i]+edge[j][3]){ 101 d[edge[j][2]] = d[i] + edge[j][3]; 102 flag = true; 103 } 104 } 105 } 106 } 107 } 108 for(int i=0;i<n;i++){ 109 for(int j=head[i];j!=-1;j=next[j]){ 110 if(d[edge[j][2]]>d[i]+edge[j][3]){ 111 return false; 112 } 113 } 114 } 115 return true; 116 } 117 118 public static void main(String[] args) { 119 Main main = new Main(); 120 main.getInput(new Scanner(System.in)); 121 122 } 123 }