布局 Layout

https://loj.ac/problem/10090

题目描述

  数轴上有n个点,有若干点对之间有一定的约束关系,约束关系有两点之间的距离大于等于x,两点之间的距离小于等于x,求到1到n的最大距离。不存在输出-1,无穷大输出-2。

思路

  由于题目中约束关系已经给出,我们只需要按照约束关系建出图后,跑一边spfa求最长路即可。而不存在解即在这个图上存在一个正环,而无穷大即对于n不可从1到达,表示n可以始终满足约束条件,或者说从1开始对n不存在约束条件,那么n就可以无穷大。不过有一点需要注意就是从1点不一定能到达其他点,而在其他联通块中可能存在负环,所以我们需要建一个源点0跑一遍spfa。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1100,M=2e4+10;
int nxt[M],to[M],w[M],tot,head[N];
int dis[N],vis[N],in[N],n;
bool exist[N];
void add_edge(int x,int y,int v)
{
    nxt[++tot]=head[x];
    head[x]=tot;
    to[tot]=y;
    w[tot]=v;
}
void spfa(int s)
{
    memset(dis,0x3f,sizeof(dis));
    memset(exist,0,sizeof(exist));
    queue<int> q;
    q.push(s);dis[s]=0;exist[s]=1;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        exist[u]=0;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]>dis[u]+w[i])
            {
                dis[v]=dis[u]+w[i];
                in[v]++;
                if(in[v]>n){printf("-1");exit(0);}
                if(!exist[v])
                {
                    exist[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
int main() 
{
    int m1,m2;
    scanf("%d%d%d",&n,&m1,&m2);
    for(int i=1;i<=n;i++)
        add_edge(0,i,0);
    for(int i=1;i<=m1;i++)
    {
        int a,b,d;
        scanf("%d%d%d",&a,&b,&d);
        add_edge(a,b,d);
    }
    for(int i=1;i<=m2;i++)
    {
        int a,b,d;
        scanf("%d%d%d",&a,&b,&d);
        add_edge(b,a,-d);
    }
    spfa(0);
    spfa(1);
    if(dis[n]!=0x3f3f3f3f)
        printf("%d",dis[n]);
    else printf("-2");
}

猜你喜欢

转载自www.cnblogs.com/fangbozhen/p/11721640.html