布局 Layout
题目描述
数轴上有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"); }