ACM: spfa求解 图论题 (对差分约束…

来源:互联网 发布:杭州创业软件官网 编辑:程序博客网 时间:2024/05/29 13:20

 

                                                                        Layout

 

Description

Like everyone else, cows like to stand close to their friendswhen queuing for feed. FJ has N (2 <= N<= 1,000) cows numbered 1..N standing along astraight line waiting for feed. The cows are standing in the sameorder as they are numbered, and since they can be rather pushy, itis possible that two or more cows can line up at exactly the samelocation (that is, if we think of each cow as being located at somecoordinate on a number line, then it is possible for two or morecows to share the same coordinate).

Some cows like each other and want to be within a certain distanceof each other in line. Some really dislike each other and want tobe separated by at least a certain distance. A list of ML (1<= ML <= 10,000) constraintsdescribes which cows like each other and the maximum distance bywhich they may be separated; a subsequent list of MD constraints (1<= MD <= 10,000) tells which cowsdislike each other and the minimum distance by which they must beseparated.

Your job is to compute, if possible, the maximum possible distancebetween cow 1 and cow N that satisfies the distanceconstraints.

Input

Line 1: Three space-separated integers: N, ML, and MD.

Lines 2..ML+1: Each line contains three space-separated positiveintegers: A, B, and D, with 1 <= A <B <= N. Cows A and B must be at most D (1<= D <= 1,000,000) apart.

Lines ML+2..ML+MD+1: Each line contains three space-separatedpositive integers: A, B, and D, with 1 <= A< B <= N. Cows A and B must be atleast D (1 <= D <= 1,000,000)apart.

Output

Line 1: A single integer. If no line-up is possible, output -1.If cows 1 and N can be arbitrarily far apart, output -2. Otherwiseoutput the greatest possible distance between cows 1 and N.

Sample Input

4 2 1
1 3 10
2 4 20
2 3 3

Sample Output

27

Hint

Explanation of the sample:

There are 4 cows. Cows #1 and #3 must be no more than 10 unitsapart, cows #2 and #4 must be no more than 20 units apart, and cows#2 and #3 dislike each other and must be no fewer than 3 unitsapart.

The best layout, in terms of coordinates on a number line, is toput cow #1 at 0, cow #2 at 7, cow #3 at 10, and cow #4 at 27.

 

题意:  又是FJ的奶牛啊. 他得奶牛之间也是有矛盾的.奶牛之间如果彼此之间喜欢就会靠的近些, 之间有最大距离

         奶牛之间彼此不喜欢就会远离, 之间有最小距离. 现在要你安排它们的站位, 从1~n. 输出1到n的最大距离.

 

解题思路:

            1. 我们从给的例子出发吧.

                设s[i] 是第i个奶牛到0位置的距离.

                 s[3] - s[1] <= 10;

                 s[4] - s[2] <= 20;

                 s[3] - s[2] >= 3 变换一下使它跟前面的一样处理  s[2] - s[3]<= -3;

               对付差分约束系统我们可以把问题抽象成图论的最短路问题. 这样分析起来就熟悉了. 最短路.

             2.很明显就是1 ~ n 走得通可以算出 10 +20 + (-3) = 27;

             3.这里就选择spfa算法求解吧. 其实bellman_ford也可以.

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAX 10005
const int INF = (1<<30);

struct node
{
 int v;
 int w;
 int next;
}edges[2*MAX];

int n;
int ml, md;
int first[MAX];
int ans[MAX];
int num;
bool vis[MAX];

void init()
{
 num = 0;
 memset(first,-1,sizeof(first));
 memset(vis,false,sizeof(vis));
 memset(ans,0,sizeof(ans));
}

void spfa()
{
 int i;
 int dist[MAX];
 queue<int>qu;
 qu.push(1);
 ans[1]++;
 vis[1] = true;

 for(i = 1; i <= n; ++i)
  dist[i] = (i == 1 ? 0 :INF);

 while( !qu.empty() )
 {
  int k = qu.front();
  qu.pop();
  vis[k] = false;

  for(int e = first[k]; e !=-1; e = edges[e].next)
  {
   if(dist[edges[e].v]> dist[k] + edges[e].w)
   {
    dist[edges[e].v]= dist[k] + edges[e].w;
    if(!vis[edges[e].v] )
    {
     if(++ans[k]> n)
     {
      printf("-1\n");
      return;
     }
     vis[edges[e].v]= true;
     qu.push(edges[e].v);
    }
   }
  }
 }

 if(dist[n] >= INF)
  printf("-2\n");
 else
  printf("%d\n",dist[n]);

}

int main()
{
 int i;
 int u, v, w;
// freopen("input.txt","r",stdin);
 while(scanf("%d %d%d",&n,&ml,&md) !=EOF)
 {
  init();
  for(i = 1; i <=ml; ++i)
  {
   scanf("%d %d%d",&u,&v,&w);
   edges[num].v= v;
   edges[num].w= w;
   edges[num].next= first[u];
   first[u] =num;
   num++;
  }

  for(i = 1; i<= md; ++i)
  {
   scanf("%d %d%d",&u,&v,&w);
   edges[num].v= u;
   edges[num].w= (-1)*w;
   edges[num].next= first[v];
   first[v] =num;
   num++;
  }

  for(int i = 1; i< n; ++i)
  {
   edges[num].v= i;
   edges[num].w= 0;
   edges[num].next= first[i+1];
   first[i+1] =num;
   num++;
  }
  spfa();
 }
 return 0;
}

         

0 0