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
  • 相关阅读:
    flask-script插件
    狗书(flask基础)
    2018.1.18纪事
    py3.6 + xadmin的自学网站搭建
    使用selenium抓取淘宝的商品信息
    pyquery操作
    requests模块
    python3里的Urllib库
    随便写点
    How many ways?? HDU
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3822729.html
Copyright © 2011-2022 走看看