HDU1534 Schedule Problem 差分约束

囧,还是暴露出了对差分约束理解的不透彻。。。

一开始根据开始和结束的关系建边,然后建立一个超级源点,连接每一个其他节点,先把这个点入队。本质上相当于把一开始所有的节点都入队了,然后做一遍最长路(最短路,怎么建边的怎么来),相当于把每一个点都作为起点做了一遍最短路,每个点的d取最大的那个。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 2000;
const int maxm = 6e5;
const int INF = INT_MAX / 4;
int first[maxn],nxt[maxm],d[maxn],qcnt[maxn];
int n,v[maxm],w[maxm],ecnt,last[maxn];
bool inq[maxn];
char buf[1024];

void adde(int uu,int vv,int ww) {
    //printf("add %d %d %d\n",uu,vv,ww);
    v[ecnt] = vv; w[ecnt] = ww;
    nxt[ecnt] = first[uu];
    first[uu] = ecnt;
    ecnt++;
}

bool spfa(int str) {
    bool bad = false;
    queue<int> q;
    for(int i = 0;i <= n;i++) {
        d[i] = -INF;
        inq[i] = false;
        qcnt[i] = 0;
    }
    q.push(str);
    qcnt[str] = 1;
    d[str] = 0;
    inq[str] = true;
    while(!q.empty()) {
        int x = q.front(); q.pop();
        inq[x] = false;
        for(int i = first[x];i != -1;i = nxt[i]) {
            if(d[v[i]] < d[x] + w[i]) {
                d[v[i]] = d[x] + w[i];
                if(!inq[v[i]]) {
                    qcnt[v[i]]++;
                    inq[v[i]] = true;
                    q.push(v[i]);
                    if(qcnt[v[i]] > n + 1) {
                        return false;
                    }
                }
            }
        }
    }
    return true;
}

void solve() {
    if(spfa(0) == false) puts("impossible");
    else {
        for(int i = 1;i <= n;i++) {
            printf("%d %d\n",i,d[i]);
        }
    }
}

int main() {
    int kase = 1;
    while(scanf("%d",&n),n) {
        printf("Case %d:\n",kase++);
        memset(first,-1,sizeof(first));
        memset(nxt,-1,sizeof(nxt));
        ecnt = 0;
        for(int i = 1;i <= n;i++) {
            scanf("%d",&last[i]);
        }
        while(scanf("%s",buf),buf[0] != ‘#‘) {
            int a,b; scanf("%d%d",&a,&b);
            if(strcmp(buf,"SAF") == 0) adde(b,a,last[b]);
            if(strcmp(buf,"FAF") == 0) adde(b,a,last[b] - last[a]);
            if(strcmp(buf,"SAS") == 0) adde(b,a,0);
            if(strcmp("FAS",buf) == 0) adde(b,a,-last[a]);
        }
        //建立超级源点
        for(int i = 1;i <= n;i++) {
            adde(0,i,0);
        }
        solve();
        puts("");
    }
    return 0;
}

  

HDU1534 Schedule Problem 差分约束

时间: 2024-08-27 00:29:16

HDU1534 Schedule Problem 差分约束的相关文章

HDOJ 1534 Schedule Problem 差分约束

差分约数: 求满足不等式条件的尽量小的值---->求最长路---->a-b>=c----> b->a (c) Schedule Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1503    Accepted Submission(s): 647 Special Judge Problem Descr

HDU1534 Schedule Problem 【差分约束系统】

Schedule Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1283    Accepted Submission(s): 534 Special Judge Problem Description A project can be divided into several parts. Each part sho

hdu3666 THE MATRIX PROBLEM --- 差分约束

这要是碰上现场赛我得被搞死 从RE到TLE到WA已疯.. 这题建图没有那么直接,通过给出的不等式关系一时想不到怎么建图 所以要对题目给的条件一定程度化简,将不等式两边取对数化简得到Sa-Sb<=c的形式 要注意w取double类型 其次,这题卡时间,根据经验加剪枝: 1.出队次数>sqrt(n)则判断有负环 2.统计总的入队次数,>2n则判断有负环 一般情况下不用这个,因为不严谨 下面两个spfa都是对的,手写队列稍快一点,上面第二个剪枝效果明显 #include<iostream

HDU1534 Schedule Problem【SPFA】【差分约束】

Schedule Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1404    Accepted Submission(s): 599 Special Judge Problem Description A project can be divided into several parts. Each part sho

HDU3666 THE MATRIX PROBLEM (差分约束+取对数去系数)(对退出情况存疑)

You have been given a matrix C N*M, each element E of C N*M is positive and no more than 1000, The problem is that if there exist N numbers a1, a2, … an and M numbers b1, b2, …, bm, which satisfies that each elements in row-i multiplied with ai and e

HDU 3666 THE MATRIX PROBLEM (差分约束)

题意:给定一个最大400*400的矩阵,每次操作可以将某一行或某一列乘上一个数,问能否通过这样的操作使得矩阵内的每个数都在[L,R]的区间内. 析:再把题意说明白一点就是是否存在ai,bj,使得l<=cij*(ai/bj)<=u (1<=i<=n,1<=j<=m)成立. 首先把cij先除到两边去,就变成了l'<=ai/bj<=u',由于差分约束要是的减,怎么变成减法呢?取对数呗,两边取对数得到log(l')<=log(ai)-log(bj)<=l

HDOJ 3666 THE MATRIX PROBLEM 差分约束

根据题意有乘除的关系,为了方便构图,用对数转化乘除关系为加减关系..... THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7486    Accepted Submission(s): 1914 Problem Description You have been given a matrix CN

HDU-1534 Schedule Problem

四种约束条件..照做就行了.. 最长路建图. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <fstream> #include <iostream> #include <deque> #define rep(i, l, r) for(int i=l;

hdu 差分约束题集

[HDU]1384 Intervals 基础差分约束★1529 Cashier Employment 神级差分约束★★★★ 1531 King 差分约束★1534 Schedule Problem 差分约束输出一组解★3440 House Man 比较好的差分约束★★3592 World Exhibition 简单★3666 THE MATRIX PROBLEM 中等★★4274 Spy's Work [先处理出欧拉序列,然后就是差分约束了...] [POJ]1201 Intervals1275