问题描述
https://cses.fi/problemset/task/1197 循环查找, 如果它有任何负权重,我的算法会打印循环,但陪审团不接受。
他们建议使用 bellman Ford 算法,但我的 dfs 也工作正常。
问题: 给你一个有向图,你的任务是找出它是否包含一个负循环,并给出这样一个循环的例子。
输入
第一行输入有两个整数 n 和 m:节点和边的数量。节点编号为 1,2,...,n。
在此之后,输入有 m 行描述边缘。每行有三个整数 a、b 和 c:从节点 a 到节点 b 有一条边,长度为 c。
输出
如果图中包含负循环,则先打印“YES”,然后按正确顺序打印循环中的节点。如果有多个负循环,您可以打印其中任何一个。如果没有负循环,打印“NO”。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define f first
#define s second
#define pb push_back
typedef pair<ll,ll> pll;
ll n,m;
const int nxm = 2.5e3 + 5;
vector<pll> adj[nxm];
bool visi[nxm];
pll parent[nxm];
void dfs(int u)
{
visi[u] = true;
// cout<<u<<" ";
for (pll v : adj[u])
{
if (visi[v.s])
{
// cout<<v.s;
int u1 = u;
// flag is for checking if the cycle has any negative weight or not
bool flag = false;
if (v.f < 0)
flag = true;
vector<int> res;
res.pb(v.s);
while (u1!=0 && u1 ^ v.s)
{
res.pb(u1);
u1 = parent[u1].s;
if (parent[u1].f < 0)
flag = true;
}
res.pb(v.s);
if (flag)
{
reverse(res.begin(),res.end());
cout << "YES" << endl;
for (int x : res)
cout << x << " ";
exit(0);
}
}
else
{
parent[v.second] = {v.f,u};
dfs(v.s);
}
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
ll a,b,c;
cin >> a >> b >> c;
adj[a].pb({c,b});
}
memset(visi,sizeof(visi));
for (int i = 1; i <= n; i++)
{
if(visi[i])
continue;
parent[i] = {0,0};
dfs(i);
}
cout << "NO";
return 0;
}
示例测试用例:
5 10
1 3 1000
2 4 1000
3 5 1000
4 1 1000
5 2 1000
1 2 -2
2 3 -2
3 4 -2
4 5 -2
5 1 -2
陪审团的回答
YES
2 3 4 5 1 2
我的回答
YES
5 2 4 5
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)