P4878 [USACO05DEC] Layout G

原题链接

大概思路

我们已知一组不等式的解可以通过建边然后求最短路/最长路来得出
而这里要求 DnD1 的最大值,所以我们要求最短路。

补充

为什么要求最短路?
对于任何一组不等式,我们都可以写成 aibici 建边含义
假设 DnD1 有最大值,那么通过这组不等式的组合,一定能得出若干个形似 DnD1kj 的式子,此时便可以得出 max(DnD1) 就等于 min(kj)

细节

  1. DiDi1 (i>1) Di1Di0
    2.要判断每条边(即每个约束)是否都满足,所以要建立超级源点,判断是否存在负环,不能以点1来判断是否存在负环,因为图不保证联通

code

#include<bits/stdc++.h>
using namespace std;
const int inf=2e9;

int dis[1010];

struct node
{
    int to,len;
};
vector<node> G[1010];
int n;
bool run(int start)
{
    int vis[1010]={0};
    bool in_q[1010]={0};
    fill(dis,dis+1004,inf);
    queue<int>  q;
    q.push(start);
    in_q[start]=1;
    dis[start]=0;

    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,len=next.len;
            if(dis[to]>dis[now]+len)
            {
                dis[to]=dis[now]+len;
                if(!in_q[to])
                {
                    q.push(to);
                }
            }
        }
    }
    return 1;
}
int main()
{
    int l,d;
    cin>>n>>l>>d;

    for(int i=1;i<=n;i++) G[0].push_back({i,0});
    for(int i=2;i<=n;i++) G[i].push_back({i-1,0});
    for(int i=1;i<=l;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        G[a].push_back({b,c});
    }

    for(int i=1;i<=d;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        G[b].push_back({a,-c});
    }



    if(!run(0)) puts("-1");
    else
    {
        run(1);
        if(dis[n]==inf) puts("-2");
        else cout<<dis[n]<<endl;
    }

    //for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
    return 0;
}

posted @   纯粹的  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示