zoukankan      html  css  js  c++  java
  • POJ3169:Layout(差分约束)

    http://poj.org/problem?id=3169

    题意:

    一堆牛在一条直线上按编号站队,在同一位置可以有多头牛并列站在一起,但编号小的牛所占的位置不能超过编号大的牛所占的位置,这里用d[i]表示编 号为i的牛所处的位置,即要满足d[i]-d[i+1]<=0,同时每两头牛之间有以下两种关系(对于输入的a b d来说):
                1>如果是喜欢关系:即需要满足d[b]-d[a]<=d
                2>如果是讨厌关系:即需要满足d[b]-a[a]>=d ……> d[a]-d[b]<=-d
       由于题目要求队伍的最大可能长度,即求满足以下三个约束条件的最大值,,由于此处是求最大值,故用Bellman_Ford算法求约束图的最短路径.
                1>对于ML有:d[b]-d[a]<=d
                2>对于MD有:d[a]-d[b]<=-d
                3>对于n个顶点的约束图有:s[i]-s[i+1]<=0(隐含条件)
        题目的解为:有负环输出-1,d[n]无穷大输出-2,其他输出dist[n].
        在差分约束系统中如果题目要求是求最小值,就将约束条件转化为">="形式,然后用Bellman_Ford算法求解约束图的最长路径,如果题目要 求的是最大值,就将约束条件转化为"<="形式,然后用Bellman_Ford算法求解约束图的最短路径.

    PS:
    (1)INF不能开得太大,可能会溢出;
    (2)数组尽量开小,不然会比较慢

    如果有负环,输出-1,如果N可以无限远,即1与N不连通,输出-2,其他情况输出1与N的最大距离。(最短路)

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <queue>
    #define N 1000001
    using namespace std;
    int n,m,k,tt;
    int head[1001],v[1001],dis[1001];
    struct node
    {
        int x,y,z;
        int next;
    } q[1000001];
    void init()
    {
        memset(head,-1,sizeof(head));
        tt=0;
    }
    void add(int xx,int yy,int zz)
    {
        q[tt].x=xx;
        q[tt].y=yy;
        q[tt].z=zz;
        q[tt].next=head[xx];
        head[xx]=tt++;
    }
    void SPFA()
    {
        for(int i=1; i<=n; i++)
        {
            dis[i]=N;
            v[i]=0;
        }
        dis[1]=0;
        v[1]=1;
        queue<int>p;
        p.push(1);
        while(!p.empty())
        {
            int ff=p.front();
            p.pop();
            v[ff]=0;
            for(int i=head[ff]; i!=-1; i=q[i].next)
            {
                if(dis[q[i].y]>dis[ff]+q[i].z)
                {
                    dis[q[i].y]=dis[ff]+q[i].z;
                    if(dis[q[i].y]<0)//不存在最短路(这题是实际问题,不会出现负边//或者根据有顶点入队列的次数大于n)
                    {
                        printf("-1
    ");
                        return ;
                    }
                    if(!v[q[i].y])
                    {
                        v[q[i].y]=1;
                        p.push(q[i].y);
                    }
                }
            }
        }
        if(dis[n]==N) printf("-2
    ");//1到n没有路
        else printf("%d
    ",dis[n]);
        return ;
    }
    int main()
    {
        int xx,yy,zz;
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            init();
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&xx,&yy,&zz);
                add(xx,yy,zz);
            }
            for(int i=1; i<=k; i++)
            {
                scanf("%d%d%d",&xx,&yy,&zz);
                add(yy,xx,-zz);
            }
            for(int i=1; i<n; i++)//隐含条件
            {
                add(i+1,i,0);
            }
            SPFA();
        }
        return 0;
    }
  • 相关阅读:
    我的操作系统复习——进程(下)
    我的操作系统复习——进程(上)
    我的操作系统复习——操作系统概述
    GO语言总结(5)——类型转换和类型断言
    GO语言总结(4)——映射(Map)
    GO语言总结(3)——数组和切片
    GO语言总结(2)——基本类型
    msl字符串截取与拆分
    ES中模糊查询的实现
    mysql纯数字的字符串排序
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/3940795.html
Copyright © 2011-2022 走看看