1. 程式人生 > >【bzoj1731】Layout 排隊佈局

【bzoj1731】Layout 排隊佈局

1731: [Usaco2005 dec]Layout 排隊佈局

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 868  Solved: 495
[Submit][Status][Discuss]

Description

Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbered, and since they can be rather pushy, it is possible that two or more cows can line up at exactly the same location (that is, if we think of each cow as being located at some coordinate on a number line, then it is possible for two or more cows to share the same coordinate). Some cows 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 ML (1 <= ML <= 10,000) constraints describes which cows like each other and the maximum distance by which they may be separated; a subsequent list of MD constraints (1 <= MD <= 10,000) tells which cows 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 cow 1 and cow N that satisfies the distance constraints.

 當排隊等候餵食時,奶牛喜歡和它們的朋友站得靠近些。FJ有N(2<=N<=1000)頭奶牛,編號從1到N,沿一條直線站著等候餵食。奶牛排在隊伍中的順序和它們的編號是相同的。因為奶牛相當苗條,所以可能有兩頭或者更多奶牛站在同一位置上。即使說,如果我們想象奶牛是站在一條數軸上的話,允許有兩頭或更多奶牛擁有相同的橫座標。一些奶牛相互間存有好感,它們希望兩者之間的距離不超過一個給定的數L。另一方面,一些奶牛相互間非常反感,它們希望兩者間的距離不小於一個給定的數D。給出ML條關於兩頭奶牛間有好感的描述,再給出MD條關於兩頭奶牛間存有反感的描述。(1<=ML,MD<=10000,1<=L,D<=1000000)你的工作是:如果不存在滿足要求的方案,輸出-1;如果1號奶牛和N號奶牛間的距離可以任意大,輸出-2;否則,計算出在滿足所有要求的情況下,1號奶牛和N號奶牛間可能的最大距離。

Input

* Line 1: Three space-separated integers: N, ML, and MD. * Lines 2..ML+1: Each line contains three space-separated positive integers: 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-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at least 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. Otherwise output the greatest possible distance between cows 1 and N.

Sample Input

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

INPUT DETAILS:

There are 4 cows. Cows #1 and #3 must be no more than 10 units
apart, 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 units apart.

Sample Output

27

四隻牛分別在0,7,10,27.

HINT

Source

Gold

 

題意:

$N$頭牛排隊,有一些牛希望自己和另一隻牛距離不超過$D$(日久生情),

還有一些牛希望自己和另一隻牛距離不小於$D$(因愛生恨)。

問滿足所有條件時$1$號牛和$N$號牛的距離最遠是多少?

 

題解:

看到形如三角形不等式的約束條件基本就可以想差分約束的建圖了。

(畢竟我好像也沒學過多少處理三角形不等式的方法吧)

詢問距離最大值一定是計算最短路的,那麼只需要將不等式轉化成$s_i-s_j\leq w$的形式即可。

轉換完成後跑$spfa$,這道題跟板有一點小區別:

  • 當圖上存在負環時,肯定不能滿足所有條件,輸出$-1$。
  • 當$dis_n=\infty$時,$n$與$1$無約束,即可以任意大,輸出$-2$。
  • 否則,輸出$dis_n$。

 

程式碼:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;
#define MAXN 100005
#define MAXM 500005
#define INF 0x3f3f3f3f
#define ll long long

int hd[MAXN],to[MAXN<<1],cnt;
int nxt[MAXN<<1],cst[MAXN<<1];
int dis[MAXN];bool vis[MAXN]; 

inline int read(){
    int x=0,f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())
        if(c=='-')
            f=-1;
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x*f;
}

inline void addedge(int u,int v,int w){
    to[++cnt]=v,cst[cnt]=w;
    nxt[cnt]=hd[u],hd[u]=cnt;
    return;    
}

inline bool spfa_dfs(int u){
    vis[u]=1;    
    for(int i=hd[u];i;i=nxt[i]){
        int v=to[i];
        if(dis[v]>dis[u]+cst[i]){
            if(vis[v]) return 0;
            dis[v]=dis[u]+cst[i];
            if(!spfa_dfs(v)) return 0;
        }
    }
    vis[u]=0;
    return 1;
}

inline void spfa_bfs(int s){
    memset(dis,63,sizeof(dis));
    memset(vis,0,sizeof(vis));
    queue<int> q;q.push(s);
    dis[s]=0;vis[s]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();vis[u]=0;
        for(int i=hd[u];i;i=nxt[i]){
            int v=to[i];
            if(dis[v]>dis[u]+cst[i]){
                dis[v]=dis[u]+cst[i];
                if(!vis[v]) 
                    q.push(v),vis[v]=1;
            }
        }
    }
    return;
}

int main(){
    int N=read(),M1=read(),M2=read();
    for(int i=1;i<=M1;i++){
        int u=read(),v=read(),w=read();
        if(u>v) swap(u,v);
        addedge(u,v,w);
    }
    for(int i=1;i<=M2;i++){
        int u=read(),v=read(),w=read();
        if(u>v) swap(u,v);
        addedge(v,u,-w); 
    } 
    for(int i=1;i<=N;i++) addedge(i,i-1,0);
    memset(dis,63,sizeof(dis));
    dis[1]=0;
    if(!spfa_dfs(1)){
        printf("-1\n");
        return 0;
    }
    spfa_bfs(1); 
    if(dis[N]>=INF){
        printf("-2\n");
        return 0;
    }
    printf("%d\n",dis[N]);
    return 0;
}