题意:给出n个点,m条正权无向边,s条负权有向边,问是否存在负环.
题解:Bellman-Ford判负环问题,套一波模板.
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 1005
struct edge
{
int u, v, dis;
};
vector<edge>e;
int dis[1005];
void Bellman_Ford(int n)
{
for (int i = 1; i <= n; i++)
dis[i] = inf;
dis[1] = 0;
for (int k = 1; k < n; k++) //先进行n-1次取点
for (int i = 0; i < e.size(); i++)
{
edge &p = e[i];
if (dis[p.u] != inf&&dis[p.u] + p.dis < dis[p.v]) //松弛
dis[p.v] = dis[p.u] + p.dis;
}
}
bool check(int n)
{
for (int i = 0; i < e.size(); i++)
{
edge &p = e[i];
if (dis[p.u] != inf&&dis[p.u] + p.dis < dis[p.v]) //判断是否还能进行松弛,若能说明存在负环
return true;
}
return false;
}
void solve(int n)
{
Bellman_Ford(n);
if (check(n))printf("YES\n");
else printf("NO\n");
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, m, s;
scanf("%d%d%d", &n, &m, &s);
e.clear();
while (m--)//m条正权无向边
{
edge p1, p2;
scanf("%d%d%d", &p1.u, &p1.v, &p1.dis);
p2.u = p1.v;
p2.v = p1.u;
p2.dis = p1.dis;
e.push_back(p1);
e.push_back(p2);
}
while (s--)//s条负权有向边
{
edge p;
scanf("%d%d%d", &p.u, &p.v, &p.dis);
p.dis = -p.dis;
e.push_back(p);
}
solve(n);
}
}