zoukankan      html  css  js  c++  java
  • 2014 Super Training #6 B Launching the Spacecraft --差分约束

    原题:ZOJ 3668 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3668

    典型差分约束题。

    将sum[0] ~ sum[n] 作为节点,A<=sum[R]-sum[L-1]<=B可以分别建边:

    x(L-1)-->xR  w = B

    xR --> x(L-1)  w = -A

    注意还有 -10000<=sum[i]-sum[i-1]<=10000 (for i in (2,n)),所以相邻点之间还要建边,(WA了很多次)这样的话就不用另加节点来使联通了,因为必会连通。如果出现负环,则无解。

    用SPFA求最短路并判负环,求出的节点的dis[i]如果为INF,则任意取值(事实上此题不会),否则dis[i]就是sum[i],然后根据sum数组两两之间差值来求出a[i]。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <queue>
    #define Mod 1000000007
    using namespace std;
    #define N 10017
    
    vector<pair<int,int> > G[N];
    int dis[N],inq[N],cnt[N];
    int sum[N];
    int n,m;
    queue<int> que;
    
    bool SPFA(int s)
    {
        int u,v,i,w;
        for(i=0;i<=n;i++)
        {
            inq[i] = 0;
            dis[i] = Mod;
            cnt[i] = 0;
        }
        while(!que.empty())
            que.pop();
        que.push(s);
        dis[s] = 0;
        cnt[s] = 1;
        inq[s] = 1;
        //for(i=0;i<=n;i++)
            //que.push(i);
        while(!que.empty())
        {
            u = que.front();
            que.pop();
            inq[u] = 0;
            for(i=0;i<G[u].size();i++)
            {
                v = G[u][i].first;
                w = G[u][i].second;
                if(dis[v] > dis[u] + w)
                {
                    dis[v] = dis[u] + w;
                    if(!inq[v])
                    {
                        inq[v] = 1;
                        cnt[v]++;
                        if(cnt[v] >= n+1)
                            return false;
                        que.push(v);
                    }
                }
            }
        }
        return true;
    }
    
    int main()
    {
        int i,j;
        int L,R,A,B;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(i=0;i<=n+3;i++)
                G[i].clear();
            while(m--)
            {
                scanf("%d%d%d%d",&L,&R,&A,&B);
                G[R].push_back(make_pair(L-1,-A));
                G[L-1].push_back(make_pair(R,B));
            }
            for(i=1;i<=n;i++)
            {
                G[i].push_back(make_pair(i-1,10000));
                G[i-1].push_back(make_pair(i,10000));
            }
            if(SPFA(0))
            {
                for(i=1;i<=n+1;i++)
                {
                    if(dis[i] != Mod)
                        sum[i] = dis[i];
                    else
                        sum[i] = sum[i-1];
                }
                printf("%d",sum[1]);
                for(i=2;i<=n;i++)
                    printf(" %d",sum[i]-sum[i-1]);
                printf("
    ");
            }
            else
                puts("The spacecraft is broken!");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Codeforces 834D The Bakery
    hdu 1394 Minimum Inversion Number
    Codeforces 837E Vasya's Function
    Codeforces 837D Round Subset
    Codeforces 825E Minimal Labels
    Codeforces 437D The Child and Zoo
    Codeforces 822D My pretty girl Noora
    Codeforces 799D Field expansion
    Codeforces 438D The Child and Sequence
    Codeforces Round #427 (Div. 2) Problem D Palindromic characteristics (Codeforces 835D)
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3822729.html
Copyright © 2011-2022 走看看