题目大意:通过虫洞可以回到过去和未来,一名科学家想通过在虫洞中无限循环回到大爆炸时代,问是否可能。
实际上是求这个有向图上是否存在负环,可以用Bellman Ford算法进行判断:在进行n-1次的松弛操作后再进行一次松弛操作,如果有节点的距离变小了,说明这个图上存在负环。

1 #include <cstdio> 2 #include <vector> 3 using namespace std; 4 #define INF 1e9 5 typedef pair<int, int> ii; 6 typedef vector<ii> vii; 7 8 int main() 9 { 10 #ifdef LOCAL 11 freopen("in", "r", stdin); 12 #endif 13 int T; 14 scanf("%d", &T); 15 while (T--) 16 { 17 int n, m; 18 scanf("%d%d", &n, &m); 19 vector<vii> AdjList(n); 20 for (int i = 0; i < m; i++) 21 { 22 int u, v, w; 23 scanf("%d%d%d", &u, &v, &w); 24 AdjList[u].push_back(make_pair(v, w)); 25 } 26 vector<int> dist(n, INF); 27 dist[0] = 0; 28 for (int i = 0; i < n-1; i++) 29 for (int u = 0; u < AdjList.size(); u++) 30 for (int j = 0; j < AdjList[u].size(); j++) 31 { 32 int v = AdjList[u][j].first, w = AdjList[u][j].second; 33 dist[v] = min(dist[v], dist[u]+w); 34 } 35 bool negative_cycle = false; 36 for (int u = 0; u < AdjList.size(); u++) 37 for (int j = 0; j < AdjList[u].size(); j++) 38 { 39 int v = AdjList[u][j].first, w = AdjList[u][j].second; 40 if (dist[v] > dist[u] + w) 41 { 42 negative_cycle = true; 43 goto s; 44 } 45 } 46 s: if (negative_cycle) printf("possible "); 47 else printf("not possible "); 48 } 49 return 0; 50 }