SPFAが負のリングを見つける---------ワームホール

農夫ジョンは彼の多くの農場を訪問している間に多くの驚くべきワームホールを発見しました。
ワームホールは非常に独特で、一方向のパスと見なすことができ、ワームホールに入る前と比較して、過去の特定の瞬間に戻ることができます。
ファーマージョンの農場には、N個のフィールド、M個のパス(双方向)、およびW個のワームホールがあります。
現在、農夫のジョンは、農場の畑から出発し、いくつかの小道やワームホールを通って過去に戻り、出発時間の前に出発地に急行できることを望んでいます。
彼は出発前に自分に会いたいと思っている。
ジョンにできるかどうか判断してください。
以下では、ジョンFが所有する農場の数と、各農場に関する完全な情報を提供します。
パスを移動するのにかかる時間は10,000秒を超えず、ワームホールが彼を元に戻すのにかかる時間は10000秒を超えないことがわかっています。
入力形式
最初の行には整数Fが含まれており、JohnにFファームがあることを示しています。
各ファームの最初の行には、3つの整数N、M、Wが含まれています。
次のM行。各行には3つの整数S、E、Tが含まれており、フィールドSとEの間にパスがあることを示します。このパスを通過するのにかかる時間はTです。
次に、行Wの各行には3つの整数S、E、およびTが含まれており、フィールドSからフィールドEに移動するワームホールがあることを示しています。このワームホールを通過した後、T秒に戻ることができます。
出力形式
合計F行が出力され、1行に1つの結果が出力されます。
ジョンが出発時刻より前に出発地に戻ることができる場合は「YES」が出力され、そうでない場合は「NO」が出力されます。
データ範囲
1≤F≤51≤F≤5

1≤N≤5001≤N≤500、

1≤M≤25001≤M≤2500、

1≤W≤2001≤W≤200、

1≤T≤100001≤T≤10000、

1≤S、E≤N1≤S、E≤N
入力サンプル:
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

出力例:
いいえ
はい

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510, M = 5210;
int n, m1, m2;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
int q[N], cnt[N];
bool st[N];
void add(int a, int b, int c){
 e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
bool spfa(){
 memset(dist, 0, sizeof dist);
 memset(cnt, 0, sizeof cnt);
 memset(st, 0, sizeof st);
  int hh = 0, tt = 0;
 for (int i = 1; i <= n; i ++){
  q[tt ++] = i;
  st[i] = true;
 }
  while(hh != tt){
  int t = q[hh ++];
  if (hh == N)   hh = 0;
  st[t] = false;
   for (int i = h[t]; ~i; i = ne[i]){
   int j = e[i];
   if (dist[j] > dist[t] + w[i]){
    dist[j] = dist[t] + w[i];
    cnt[j] = cnt[t] + 1;
    if (cnt[j] >= n)    return true;
    if (!st[j]){
     q[tt ++] = j;
     if (tt == N)   tt = 0;
     st[j] = true;
    }
   }
  }
 }
  return false;
}
int main(){
 int T;
 cin >> T;
 while(T --){
  scanf("%d%d%d", &n, &m1, &m2);
  memset(h, -1, sizeof h);
  idx = 0;
    for (int i = 0; i < m1; i ++){
   int a, b, c;
   scanf("%d%d%d", &a, &b, &c);
   add(a, b, c), add(b, a, c);
  }
    for (int i = 0; i < m2; i ++){
   int a, b, c;
   scanf("%d%d%d", &a, &b, &c);
   add(a, b, -c);
  }
    if (spfa())    puts("YES");
  else           puts("NO");
 }
  return 0;
}
公開された元の記事164件 いいね112 訪問者6771

おすすめ

転載: blog.csdn.net/qq_45772483/article/details/105469818