hdu3592(差分約束)

Nowadays, many people want to go to Shanghai to visit the World Exhibition. So there are always a lot of people who are standing along a straight line waiting for entering. Assume that there are N (2 <= N <= 1,000) people numbered 1..N who are standing in the same order as they are numbered. It is possible that two or more person line up at exactly the same location in the condition that those visit it in a group. 

There is something interesting. Some like each other and want to be within a certain distance of each other in line. Some really dislike each other and want to be separated by at least a certain distance. A list of X (1 <= X <= 10,000) constraints describes which person like each other and the maximum distance by which they may be separated; a subsequent list of Y constraints (1 <= Y <= 10,000) tells which person dislike each other and the minimum distance by which they must be separated. 

Your job is to compute, if possible, the maximum possible distance between person 1 and person N that satisfies the distance constraints. 

Input

First line: An integer T represents the case of test. 

The next line: Three space-separated integers: N, X, and Y. 

The next X lines: Each line contains three space-separated positive integers: A, B, and C, with 1 <= A < B <= N. Person A and B must be at most C (1 <= C <= 1,000,000) apart. 

The next Y lines: Each line contains three space-separated positive integers: A, B, and C, with 1 <= A < B <= C. Person A and B must be at least C (1 <= C <= 1,000,000) apart. 

Output

For each line: A single integer. If no line-up is possible, output -1. If person 1 and N can be arbitrarily far apart, output -2. Otherwise output the greatest possible distance between person 1 and N.

Sample Input

1
4 2 1
1 3 8
2 4 15
2 3 4

Sample Output

19

題意:求符合題意的最小集合的元素個數
題目要求的是求的最短路,
則對於 不等式  f(b)-f(a)>=c,建立 一條 b 到 a 的邊 權值爲 c,則求的最長路 即爲 最小值(集合)
並且有隱含條件:0<=f(a)-f(a-1)<=1  則有邊權關係(a,a-1,0)以及(a-1,a,-1);
將源點到各點的距離初始化爲INF(無窮大),其中之1爲0,最終求出的最短路滿足 它們與該點之間相互差值最大
差分約束
 在實際的應用中,一般使用SPFA(Shortest Path Fast Algorithm)算法來實現。
  差分約束系統中源點到每個點的距離確定
  關於Dist[]的初始化化
  1.如果將源點到各點的距離初始化爲0,最終求出的最短路滿足 它們之間相互最接近了
  2.如果將源點到各點的距離初始化爲INF(無窮大),其中之1爲0,最終求出的最短路滿足 它們與該點之間相互差值最大。
  3.差分約束系統的確立要根據自己確定的約束條件,從約束點走向被約束點
  連邊一般有兩種方法,第一種是連邊後求最長路的方法,第二種是連邊後求最短路的方法。
  例:d[x]-d[y]>=Z
  如果想連邊後求最長路 那麼將不等式變形爲這種形式 d[x]>=d[y]+z y---x連一條權值爲z的邊
  求最短路則變形成d[y]<=d[x]-z x---y連一條權值爲-z的邊。
  如果是別的不等式,也可以根據情況變形。但是要保證的是 兩個變量(x,y)的係數一定要是正的。而常量則不一定。
第一:
感覺難點在於建圖
第二:
①:對於差分不等式,a - b <= c ,建一條 b 到 a 的權值爲 c 的邊,求的是最短路,得到的是最大值
②:對於不等式 a - b >= c ,建一條 b 到 a 的權值爲 c 的邊,求的是最長路,得到的是最小值
③:存在負環的話是無解
④:求不出最短路(dist[ ]沒有得到更新)的話是任意解
第三:
一種建圖方法:
設x[i]是第i位置(或時刻)的值(跟所求值的屬性一樣),那麼把x[i]看成數列,前n項和爲s[n],則x[i] = s[i] - s[i-1];
那麼這樣就可以最起碼建立起類似這樣的一個關係:0 <= s[i] - s[i-1] <= 1;
其他關係就要去題目探索了

 在這裏可能會有疑惑,最大距離爲什麼是求最短路。

因爲你是吧題目的邊轉化成了s[i]-s[j]>d;的形式。

 for(int i=2;i<=n;i++){
            addEdge(i,i-1,0);
        }別忘了添加這幾條邊。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define INF 0x3f3f3f3f
#define MAXN (50000+10)
using namespace std;
struct Edge
{
    int from, to, dd,next;
    Edge(){}
    Edge(int fro,int t,int d,int net):from(fro),to(t),dd(d),next(net){}
}edge[3*MAXN];
int head[MAXN], edgenum;
bool vis[MAXN];
int dist[MAXN];
int tot[MAXN];
int n;
void init()
{
    edgenum = 0;
    memset(head,-1,sizeof(head));
}
void addEdge(int u, int v,int dist)
{
    Edge E = Edge(u, v, dist,head[u]);
    edge[edgenum] = E;
    head[u] = edgenum++;
}
int SPFA(int s, int *d)
{
    queue<int> Q;
    memset(vis,false,sizeof(false));
    memset(tot,0,sizeof(tot));
    tot[s]=1;
    d[s] = 0;
    vis[s] = true;
    Q.push(s);
    while(!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        vis[u] = false;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            Edge E = edge[i];
            if(d[E.to] > d[u] + E.dd)
            {
                d[E.to] = d[u] + E.dd;
                if(!vis[E.to])
                {
                    tot[E.to]++;
                    if(tot[E.to]>n)
                    {
                        return 0;
                    }
                    vis[E.to] = true;
                    Q.push(E.to);

                }
            }
        }
    }
    return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
    init();
     memset(dist,INF,sizeof(dist));
     int x,y;
     scanf("%d%d%d",&n,&x,&y);
     for(int i=1;i<=x;i++)
     {
         int a,b,c;
         scanf("%d%d%d",&a,&b,&c);
         addEdge(a,b,c);
     }
     for(int i=1;i<=y;i++)
     {
         int a,b,c;
          scanf("%d%d%d",&a,&b,&c);
          addEdge(b,a,-c);
     }
     for(int i=2;i<=n;i++){
			addEdge(i,i-1,0);
		}
     if(SPFA(1,dist)==0)
     {
         printf("-1\n");
     }
     else
     {
         if(dist[n]==INF)
         {
             printf("-2\n");
         }
         else
         {
             printf("%d\n",dist[n]);
         }
     }
}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章