P5960 【模板】差分约束

原题链接

题解

我一直苦苦思考为什么要建边,现在我明白了,如果令 \(x_i\) 代表离源点的最短路径长度的话,建边之后,\(x_i-x_j<=y_k\) 一定成立
只有当出现负环的时候说明条件出现了矛盾

太神了

为什么负环会出现矛盾?
简单认识一下,如果出现负环,代表每到一个点就至少有一条边的约束不满足

code

#include<bits/stdc++.h>
using namespace std;
queue<int> q;
int in_q[5005]={0};
int vis[5006]={0};
int dis[5005]={0};
int n,m;
struct node
{
    int to,val;
};
vector<node> G[5005];
int fuhuan()
{
    memset(dis,0x3f,sizeof dis);

    queue<int> q;
    dis[0]=0;
    q.push(0);
    in_q[0]=1;
    while(q.size())
    {
        int now=q.front();
        q.pop();
        in_q[now]=0;
        vis[now]++;
        if(vis[now]>n) return 0;
        for(auto next:G[now])
        {
            int to=next.to,val=next.val;
            if(dis[now]+val<dis[to])
            {
                dis[to]=dis[now]+val;
                if(!in_q[to])
                {
                    q.push(to);
                    in_q[to]=1;
                }
            }
        }
    }
    return 1;
}
int main()
{
    cin>>n>>m;

    for(int i=1;i<=m;i++)
    {
        int x,y,v;
        cin>>x>>y>>v;
        G[y].push_back({x,v});
    }

    for(int i=1;i<=n;i++) G[0].push_back({i,0});

    if(!fuhuan()) puts("NO");
    else for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
    return 0;
}

posted @ 2024-04-04 21:16  纯粹的  阅读(10)  评论(0编辑  收藏  举报