1 条题解

  • 0
    @ 2024-1-18 16:39:28

    求1号奶牛到n号奶牛的距离,可以想到用最短路来做。

    不存在满足条件的方案在差分约束中等价于存在负环

    1号和n号没有限制等价于1号点走不到n号点

    差分约束等价转换

    排队顺序和编号顺序相同等价于d[i]d[i+1]d[i] \leq d[i+1] ,那么存在n号点可以到所有点

    好感:d[a]d[b]Ld[a]-d[b] \leq L 等价于 d[a]d[b]+Ld[a] \leq d[b]+L

    反感:d[a]d[b]Dd[a]-d[b] \geq D等价于 d[b]d[a]Dd[b] \leq d[a]-D

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010,M=10010*3+10,INF=0x3f3f3f3f;
    int n,m1,m2;
    int h[N],e[M],w[M],ne[M],idx;
    int dist[N];
    int q[N],cnt[N];
    bool st[N];
    void add(int a,int b,int c)
    {
        e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
    }
    bool spfa(int x) //最短路判断负环
    {
        
        memset(dist,0x3f,sizeof dist);
        memset(st,0,sizeof st);
        memset(cnt,0,sizeof cnt);
        queue<int> q;
        q.push(x);
        st[x]=true;
        dist[x]=0;
        while(q.size())
        {
            int t=q.front();
            st[t]=false;
            q.pop();
            for(int i=h[t];i!=-1;i=ne[i])
            {
                int j=e[i];
                if(dist[j]>dist[t]+w[i]) //距离可以更小
                {
                    dist[j]=dist[t]+w[i];
                    cnt[j]=cnt[t]+1;
                    if(cnt[j]>=n) return true; //负环 
                    if(!st[j])
                    {
                        q.push(j);
                        st[j]=true;
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        cin>>n>>m1>>m2;
        memset(h,-1,sizeof h);
        for(int i=1;i<n;i++) add(i+1,i,0);  //s[i]<=s[i+1]
        while(m1--) //好感
        {
            int a,b,c;
            cin>>a>>b>>c;
            if(a>b) swap(a,b); //a<=b
            add(a,b,c); //s[b]<=s[a]+c
        }
        while(m2--) //反感
        {
            int a,b,c;
            cin>>a>>b>>c;
            if(a>b) swap(a,b); //a<=b
            add(b,a,-c); //s[a]<=s[b]-c
        }
        if(spfa(n)) puts("-1"); //判断是否存在负环 
        else
        {
            spfa(1); //从起点走到n
            if(dist[n]==INF) puts("-2"); //不存在1到n的最短路(说明1到n不连通) 
            else cout<<dist[n]<<endl;  //利用最短路就求最短路的最大值 
        }
        return 0;
    }
    
    • 1

    信息

    ID
    756
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者