题意:
一堆牛在一条直线上按编号站队,在同一位置可以有多头牛并列站在一起,但编号小的牛所占的位置不能超过编号大的牛所占的位置,这里用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#include #include #include #include #define N 1000001using 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 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\n"); return ; } if(!v[q[i].y]) { v[q[i].y]=1; p.push(q[i].y); } } } } if(dis[n]==N) printf("-2\n");//1到n没有路 else printf("%d\n",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