题目链接
https://icpcarchive.ecs.baylor.edu/external/68/6800.pdf
bellman-ford照模板打了一段,能够找到负权回路,问题就是判断0点在不在负权回路中了,于是写了个记忆化dfs。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<vector> using namespace std; #define MAX 0x3f3f3f3f #define N 10100 int nodenum, edgenum; typedef struct Edge { int u, v; int cost; }Edge; Edge edge[N]; int dis[N]; bool vis[N], dp[N]; vector<int> G[N]; bool dfs(int n) { if (n == 0) return true; if (vis[n]) return dp[n]; vis[n] = true; for (int i = 0; i < G[n].size(); i++) { if (dfs(G[n][i])) { return dp[n] = true; } } return dp[n]=false; } bool Bellman_Ford() { for (int i = 0; i < nodenum; ++i) dis[i] = (i == 0 ? 0 : MAX); for (int i = 0; i < nodenum - 1; ++i) for (int j = 0; j < edgenum; ++j) if (dis[edge[j].v] > dis[edge[j].u] + edge[j].cost) { dis[edge[j].v] = dis[edge[j].u] + edge[j].cost; } bool flag = 1; for (int i = 0; i < edgenum; ++i) if (dis[edge[i].v] > dis[edge[i].u] + edge[i].cost) { if (dfs(edge[i].u)) { flag = 0; break; } } return flag; } int main() { int casen; cin >> casen; for (int cas = 1; cas <= casen;cas++) { scanf("%d%d", &nodenum, &edgenum); memset(dis, 0, sizeof(dis)); memset(vis, false, sizeof(vis)); memset(dp, false, sizeof(dp)); dp[0] = vis[0] = true; for (int i = 0; i < N; i++) G[i].clear(); for (int i = 0; i < edgenum; i++) { scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].cost); G[edge[i].u].push_back(edge[i].v); } int ok=Bellman_Ford(); if(!ok)printf("Case #%d: possible\n", cas); else printf("Case #%d: not possible\n", cas); } }
时间: 2024-10-14 17:47:20