POJ 3169 Layout 差分约束
题意:N个牛排成一队,1~N每头牛的前后位置和序号一致(序号小的在前面),两头牛如果关系好,就希望离得近一点,关系不好就希望离得远一点,现在给出一系列关系(每行关系三个数),每行表示两头牛,以及他们之间距离最大(或距离最小)是多少,求1号到N号牛的最大距离是多少,如果根据题目给的数据,牛不能排成一排,输出-1,如果1到N的距离任意,输出-2 否则输出最大距离
分析:
根据题目很容易列出一组不等式,有一个隐含条件,后一头牛的坐标一定大于等于钱一头牛(xi+1-xi>=0)求最大距离,所以就用spfa(或BellMan_Ford)求1~N的最短路,如果存在负环,说明不能排成一排,输出-1,如果dis[N]==inf(等于无穷大),输出-2,否则输出最大距离
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #define inf 1<<29 #define nMAX 1002 using namespace std; int dis[nMAX],head[nMAX]; int s_edge,n; struct Edge { int u,v,w,nxt; }edge[40005]; void addedge(int u,int v,int w) { s_edge++; edge[s_edge].u=u; edge[s_edge].v=v; edge[s_edge].w=w; edge[s_edge].nxt=head[u]; head[u]=s_edge; } bool BellMan_Ford() { int i,u,v; bool fg; for(i=2;i<=n;i++) dis[i]=inf; dis[1]=0; for(i=1;i<=n+1;i++) { fg=1; for(int e=1;e<=s_edge;e++) { u=edge[e].u,v=edge[e].v; if(dis[v]-dis[u]>edge[e].w) { dis[v]=dis[u]+edge[e].w; fg=0; } } if(fg)break; } if(fg)return 1; return 0; } int main() { int d1,d2,i,j,k; while(~scanf("%d%d%d",&n,&d1,&d2)) { memset(head,0,sizeof(head)); s_edge=0; while(d1--) { scanf("%d%d%d",&i,&j,&k); addedge(i,j,k); //<= } while(d2--) { scanf("%d%d%d",&i,&j,&k); addedge(j,i,-k); //<= } for(i=1;i<n;i++) addedge(i+1,i,0); bool fg=BellMan_Ford(); if(!fg)printf("-1\n"); else { if(dis[n]==inf)printf("-2\n"); else printf("%d\n",dis[n]); } } return 0; }