首页 > 其他 > 详细

传送 差分约束

时间:2020-01-20 17:44:27      阅读:60      评论:0      收藏:0      [点我收藏+]

题意:

题目描述
\(X\) 国有 \(N\) 座城市,由 \(N-1\) 条道路连接形成了一棵树,每条边都有边权 \(wi\) 表示经过这条边需要 \(wi\) 的时间。为了方便出行,\(X\) 国计划在每座城市建造一座传送装置,它们两两之间可以进行传送。传送并不是即时的,初始时你需要给每个传送装置设置一个参数 \(ai\),从装置 \(i\) 传送到装置 \(j\) 需要花费 \(|ai-aj|\) 的时间。
\(X\) 国并不希望得不偿失的情况发生,因此不能有任意两个城市之间通过传送需要的时间超过走路时间。同时,由于传送装置受每个城市的地质情况限制,每个城市的传送装置参数 \(ai\) 只能是区间 \([li, ri]\) 之内。当然你也可以对城市的地质进行改造,花费 \(x\)的代价可以使所有城市能接受的参数区间扩大为 \([li- x, ri + x]\)。代价必须是一个非负整数。
问在不进行改造的情况下,能否找到一种安排 \(ai\) 的方案,满足上述所有要求。有时你还需要回答在允许进行改造的情况下,最少花费多少代价进行改造,可以找到一种方案满足要求 (如果不需要改造就可满足则输出 \(0\))。
输入格式
第一行两个整数 \(T,typ\),表示数据组数和数据类型。
对于每组数据,第一行一个整数 N 表示城市的数量。
接下来一行 \(N\) 个整数,第 \(i\) 个表示 \(li\)
接下来一行 \(N\) 个整数,第 \(i\) 个表示 \(ri\)
接下来 \(N-1\) 行,每行三个整数 \(u,v,w\),表示一条道路连接 \(u\)\(v\),权值为\(w\)
输出格式
对于每组数据,如果 \(typ = 0\),则输出一行一个 0(可以满足要求) 或 1(不满足要求)。
如果 \(typ = 1\),则输出一行一个整数表示需要的最小代价。
样例输入
1 1
4
1 3 5 7
2 4 6 8
1 2 1
4
1 3 2
1 4 1
样例输出
2
数据范围与约定
对于 \(20\)% 的数据,\(1 ≤ N ≤ 5,w, |li|, |ri| ≤ 8;\)
对于 \(40\)% 的数据,\(1 ≤ N ≤ 70\);
对于 \(65\)% 的数据,\(1 ≤ N ≤ 1000\);
对于额外 \(15\)% 的数据, 保证 \(w = 0\)
对于 \(100\)% 的数据,保证 \(1 ≤ T ≤ 3\),\(typ ∈ {0or1},1 ≤ N ≤ 10^6,0 ≤ w, |li|, |ri| ≤ 109\)
在所有测试点内,均匀分布着约 \(20\)% 的数据,保证 \(typ = 0\)

思路:

首先发现这道题条件稍显繁琐,考虑将它进行简化
仔细读题,一种差分约束的感觉扑面而来
于是在原树的基础上新设一个点T,
向每个节点连边权为ri的单向边,由每个节点向T连边权为-li的单向边
于是发现是否有解取决于是否存在负环。
typ=0情况解决
typ=1时,不难发现其单调性,二分答案判断即可
至于如何判断负环,可用树形DP或spfa

启发:

差分约束加的边可以与原图结合在一起

p.s. 此题好像可以不用二分,可惜我太菜了。。。

code:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int tot,t,n,top;
int l[N],r[N];
int fi[N],ne[N<<1],to[N<<1],w[N<<1];
int sta[N];
long long d[N];
bool type,insta[N];
inline int read()
{
    int s=0,w=1; char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')w=-1;
    for(;isdigit(ch);ch=getchar())s=(s<<1)+(s<<3)+(ch^48);
    return s*w;
}
inline void add(int x,int y,int s)
{
    ne[++tot]=fi[x],fi[x]=tot,to[tot]=y,w[tot]=s;
}
bool dfs_spfa(int u,int pos)
{
    sta[++top]=u;insta[u]=true;
    for(int i=fi[u];i;i=ne[i])
    {
        int v=to[i];
        if(d[u]+1ll*w[i]<d[v])
        {
            if(insta[v])return true;
            d[v]=d[u]+1ll*w[i];
            if(dfs_spfa(v,pos))return true;
        }
    }
    --top;insta[u]=false;
    return false;
}
inline bool go(int u,int pos)
{
    for(int i=1;i<=n;++i)
        d[i]=1e15,insta[i]=false;
    d[n+1]=0;
    top=0;
    return dfs_spfa(u,pos);
}
inline bool ck(int pos)
{
    for(int i=1;i<=n;++i)w[i+2*n-2]+=pos;
    for(int i=1;i<=n;++i)w[i+3*n-2]+=pos;
    bool ff=go(n+1,pos);
    for(int i=1;i<=n;++i)w[i+2*n-2]-=pos;
    for(int i=1;i<=n;++i)w[i+3*n-2]-=pos;
    return !ff;
}
inline void clear()
{
    tot=0;
    for(int i=1;i<=n+1;++i)fi[i]=0;
}
int main()
{
//  freopen("teleport.in","r",stdin);
//  freopen("teleport.out","w",stdout);
    t=read(),type=read();
    while(t--)
    {
        n=read();
        bool flag=0;
        for(int i=1;i<=n;++i)l[i]=read();
        for(int i=1;i<=n;++i)r[i]=read();
        for(int i=1;i<n;++i)
        {
            int u=read(),v=read(),_w=read();
            add(u,v,_w),add(v,u,_w);
            if(_w) flag=1;
        }
        int mx=-1e9;
        for(int i=1;i<=n;++i)mx=max(mx,l[i]);
        int mn=1e9;
        for(int i=1;i<=n;++i)mn=min(mn,r[i]);
        if(mx<=mn){puts("0");clear();continue;}
        int ans=mx-mn;
        if(!flag)
        {
            if(!type) puts("1");
            else printf("%d\n",(ans&1)?(ans/2+1):(ans>>1));
            clear();continue;
        }
        for(int i=1;i<=n;++i)add(i,n+1,-l[i]);
        for(int i=1;i<=n;++i)add(n+1,i,r[i]);
        if(!type)
        {
            if(go(n+1,0)) puts("1");
            else puts("0");
            clear();
            continue;
        }
        int ll=0,rr=ans;
        while(ll<rr)
        {
            int mid=ll+rr>>1;
            if(ck(mid)) rr=mid;
            else ll=mid+1;
        }
        printf("%d\n",rr);
        clear();
    }
    return 0;
}

考场代码+改动,有些繁琐

传送 差分约束

原文:https://www.cnblogs.com/zmyzmy/p/12218533.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!