zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",i,d[i]);
            }
        }
    }
    
    int main() {
        int kase = 1;
        while(scanf("%d",&n),n) {
            printf("Case %d:
    ",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;
    }
    

      

  • 相关阅读:
    Spring(二) Spring装配Bean的几种方式
    Spring(一) Spring配置文件中classpath和classpath*的区别
    学习响应式编程 Reactor (5)
    学习响应式编程 Reactor (4)
    学习响应式编程 Reactor (3)
    学习响应式编程 Reactor (2)
    学习响应式编程 Reactor (1)
    学习Java 8 Stream Api (5)
    学习Java 8 Stream Api (4)
    Spring WebFlux 学习笔记
  • 原文地址:https://www.cnblogs.com/rolight/p/3860084.html
Copyright © 2011-2022 走看看