题目链接
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);
}
}