负权环求问
  • 板块学术版
  • 楼主chenruikai
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/7/11 16:14
  • 上次更新2024/7/11 16:59:22
查看原帖
负权环求问
1041549
chenruikai楼主2024/7/11 16:14

模板题 P3385P3385,大概就是让你判断从节点 11 有没有能到的负权环。

虽然知道了应使用 SPFASPFA 大法,但不知道为什么不能这样做(或者说是代码中有些什么毛病):

通过 tarjantarjan 中找强连通分量的方法(也就是访问最浅的深度与其自己的深度的比较)找到环时,判断是否权值和为负来确认(代码中使用了根节点与节点路径长进行判断)。

代码:

/*
tarjan{if(deep[nextpos] > deep[pos] && dis[pos] < dis[nextpos])}
*/
#include <bits/stdc++.h>
using namespace std;

#define unclear -1
struct cell
{
    int deep;
    vector <int> con;
    vector <int> wei;
    int dis;
    bool vis;
};
cell point[2005];
int pointnum;
void addedge(int frompos , int endpos , int wei)
{
    point[frompos].con.push_back(endpos);
    point[frompos].wei.push_back(wei);
}
void compute_init()
{
    for(int i = 0;i < pointnum;i++)
        point[i].vis = false;
    point[0].deep = 0;
    point[0].dis = 0;
}
bool compute_circle(int pos)
{
    point[pos].vis = true;
    for(unsigned long long int i = 0;
        i < point[pos].con.size();i++)
    {
        int nextpos = point[pos].con[i];
        if(point[nextpos].vis == true)
        {
            if(point[pos].dis + point[pos].wei[i] < point[nextpos].dis)
                return true;
        }
        else if(point[nextpos].vis == false)
        {
            point[nextpos].deep = point[pos].deep + 1;
            point[nextpos].dis = point[pos].dis + point[pos].wei[i];
            if(compute_circle(nextpos) == true)
                return true;
        }
    }
    point[pos].vis = false;
    return false;
}
int main()
{
    int test_times , openum;
    cin >> test_times;
    while(test_times--)
    {
        cin >> pointnum >> openum;
        for(int i = 0;i < pointnum;i++)
        {
            point[i].con.clear();
            point[i].wei.clear();
        }
        {
            int frompos , endpos , wei;
            for(int i = 0;i < openum;i++)
            {
                cin >> frompos >> endpos >> wei;
                if(wei >= 0)
                {
                    addedge(frompos - 1 , endpos - 1 , wei);
                    addedge(endpos - 1 , frompos - 1 , wei);
                }
                else
                    addedge(frompos - 1 , endpos - 1 , wei);
            }
        }
        compute_init();
        cout << (compute_circle(0) == true ? "YES\n" : "NO\n");
    }
    return 0;
}

运行结果大多数 TLETLE,但鉴于我之前细节打错无 TLETLE 以及复杂度不高来看,他应该并不会 TLETLE。经数据后,发现他到了死循环中,问各位大佬如何改改。

2024/7/11 16:14
加载中...