POJ_3169_差分约束+bellman_ford

来源:互联网 发布:连接oracle数据库工具 编辑:程序博客网 时间:2024/05/06 12:54

//============================================================================
// Name        : POJ_3169.cpp
// Author      : tiger
// Version     :
// Copyright   : Your copyright notice
// Description : 对于差分约束理解的还不透彻!!!现理解如下:
//    差分约束:
//    在图论的最短路径中有min[u]+dist(u,v) >= min[v]---> min[v]-min[u] <= dist(u,v);
//    而dist(u,v)是u到v的权值;
//    在某些约束性问题中有如下模型:
//    x2 - x1 <= y1;
//    x3 - x2 <= y2;
//     .
//     .未必是连续,也未必一定是xn 与 x[n-1]的关系
//     .
//    xn - x[n-1] <= y[n-1];
//    求xn - x1 的最大值
//
//    对于此模型,可将xn - xn-1 <= y1看做dist(x[n-1],xn) = y[n-1];
//    则1到n的最短路径极为所求
//    为什么所问是最大,所求是最短呢?
//    其实就是求出一些y值之和(1到n的路径),作为xn与x1之间的差值,
//    路径越长差值越大,路径越短差值越小。
//    注意上方的约束条件是xp-xq<=ym;这里是"<=",即xp与xq之间不能远于Ym,
//    可以近不能远,如果选择1到n最大差值会造成某些点之间距离超过ym。
//
//    本题解法如下:
//     保证a<b,因为本题中按1..n排列在一直线xn >= x[n-1],故有
//    xn - x[n-1]>= 0 --> x[n-1]- xn <= 0
//
//    对于like:a b d
//    即  b - a <= d -->dist(a,b) = d;
//
//    对于hate: a b d
//    即 b - a >= d --> a - b <= -d -->dist(b,a) = -d;
//    最后求1到n的最短路径,存在负环输出-1,距离无穷大输出-2.
//============================================================================

#include <iostream>
#include <stdio.h>
using namespace std;
#define MAXN 1002
#define inf 1000000000

typedef int elem_t;
elem_t mat[MAXN][MAXN];
elem_t  _min[MAXN];


int bellman_ford(int n,int s,elem_t* min){
 int v[MAXN],i,j,k,tag;
 for (i=0;i<n;i++)
  min[i]=inf,v[i]=0;
 for (min[s]=0,j=0;j<n;j++){
  for (k=-1,i=0;i<n;i++)
   if (!v[i]&&(k==-1||min[i]<min[k]))
    k=i;
  for (v[k]=1,i=0;i<n;i++)
   if (!v[i]&&mat[k][i]>=0&&min[k]+mat[k][i]<min[i])
    min[i]=min[k]+mat[k][i];
 }
 for (tag=1,j=0;tag&&j<=n;j++)
  for (tag=i=0;i<n;i++)
   for (k=0;k<n;k++)
    if (min[k]+mat[k][i]<min[i])
     min[i]=min[k]+mat[k][i],tag=1;
 return j<=n;
}


int main()
{
 freopen("in", "r", stdin);
 int n, ml, md;
 int i, j, k, a, b;
 scanf("%d %d %d", &n, &ml, &md);
 for (i = 0; i < n; i++)
 {


  for (j = 0; j < n; j++)
   {
    mat[i][j] = inf;
   }
  mat[i][i] = 0;

 }
 for(i  =0; i < n; i++)
 {
  mat[i+1][i] = 0;
 }
 for (i = 0; i < ml; i++)
 {
  scanf("%d %d %d", &a, &b, &k);

  if (a > b)
  {
   a = a ^ b;
   b = a ^ b;
   a = a ^ b;

  }

  mat[--a][--b] = k;
 }
 for (i = 0; i < md; i++)
 {
  scanf("%d %d %d", &a, &b, &k);

  if (a > b)
  {
   a = a ^ b;
   b = a ^ b;
   a = a ^ b;

  }

  mat[--b][--a] = -k;
 }
 ;

 if(bellman_ford( n,0,_min) ==  0)
  printf("-1/n");
 else
  if(_min[n-1] >= inf)
  printf("-2/n");
  else

 printf("%d/n",_min[n-1]);
 return 0;
}