求助:看起来感觉没问题,但就是会错
查看原帖
求助:看起来感觉没问题,但就是会错
492153
nanzjz1楼主2021/7/16 20:09

能过洛谷的数据,但一些别的数据就过不了

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int head[2010], edge_number, dis[2010], cnt[2010], n, m;//cnt用于记录每个点的最短路径的边数,令cnt[1]=1,则对于任意一点point,cnt[point]>m时说明有负环
bool inq[2010];//点是否在队列中

//下面的是链式前向星
struct Edge
{
    int nxt, v, w;
}edge[6010];
inline void add_edge(int u, int v, int w)
{
    edge[++edge_number].nxt = head[u];
    edge[edge_number].v = v;
    edge[edge_number].w = w;
    head[u] = edge_number;
}
//上面的是链式前向星
inline void spfa()
{
    queue<int>q;//每次建一个队列
    q.push(1); inq[1] = true;//压入初始点1
    while (!q.empty())
    {
        int u = q.front(); q.pop(); inq[u] = false;//取出队头
        for (int j = head[u]; j; j = edge[j].nxt)//循环遍历每一个队头指向的点
        {
            int& v = edge[j].v;//方便一点,用v表示当前遍历到的边的终点
            if (cnt[v] > m)//如果边数超过m了那就结束函数
            {
                printf("YES\n");
                return;
            }
            if (dis[v] > dis[u] + edge[j].w)
            {
                if (!inq[v])
                {
                    q.push(v); inq[v] = true;
                }
                dis[v] = dis[u] + edge[j].w;
                cnt[v] = cnt[u] + 1;//更新了距离之后也更新边数
            }
            if (cnt[v] > m)//如果边数超过m了那就结束函数
            {
                printf("YES\n");
                return;
            }
        }
    }//程序能走到这里说明没有负环 输出
    printf("NO\n"); return;
}
int main()
{

    int t; scanf("%d", &t);
    for (; t; t--)
    {//下面是各种清零
        memset(head, 0, sizeof(head));
        memset(dis, 0x3f3f3f3f, sizeof(dis));
        memset(inq, 0, sizeof(inq));
        memset(cnt, 0, sizeof(cnt));
        memset(edge, 0, sizeof(edge));
        dis[1] = 0; cnt[1] = 0; edge_number = 0;//初始化
        scanf("%d%d", &n, &m);
        for (int h = 0; h < m; h++)
        {
            int u, v, w; scanf("%d%d%d", &u, &v, &w);
            if (w >= 0)
            {//正边权就一来一回
                add_edge(u, v, w);
                add_edge(v, u, w);
            }
            else
            {//负边权就有去无回
                add_edge(u, v, w);
            }
        }
        spfa();
    }
    return 0;
2021/7/16 20:09
加载中...