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;
}

浙公网安备 33010602011771号