POJ 3169 Layout 差分约束

题意:N个牛排成一队,1~N每头牛的前后位置和序号一致(序号小的在前面),两头牛如果关系好,就希望离得近一点,关系不好就希望离得远一点,现在给出一系列关系(每行关系三个数),每行表示两头牛,以及他们之间距离最大(或距离最小)是多少,1号到N号牛的最大距离是多少,如果根据题目给的数据,牛不能排成一排,输出-1,如果1N的距离任意,输出-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;
}

  

 

posted @ 2012-08-16 11:37  快乐.  阅读(170)  评论(0编辑  收藏  举报