zoukankan      html  css  js  c++  java
  • 算法竞赛进阶指南 图论 最短路

    341 最优贸易

    题意:一张图,由单向边和双向边组成,每个节点有固定的权值,求从1走到n的最大权值之差

    (不知道为啥放最短路里,明明一个bfs就可以解决了

    存边时除了单向双向边要注意,还要存一张反边图

    bfs一遍记录从1到n每个节点到1的最小权值

    再bfs一遍跑反边图,记录从n到1每个节点到n的最大权值

    最后遍历一遍统计最大差值就ok了

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<list>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> P;
    typedef long double ld;
    #define mem(x) memset(x, 0, sizeof(x))
    #define me(x) memset(x, -1, sizeof(x))
    #define fi first
    #define se second
    #define fo(i,n) for(i=0; i<n; i++)
    #define sc(x) scanf("%I64d", &x)
    #define sca(n,m) scanf("%I64d%I64d", &n, &m)
    #define pr(x) printf("%I64d
    ", x)
    #define pri(x) printf("%I64d ", x)
    #define lowbit(x) x&-x
    const ll MOD = 1e9 + 7;
    const ll oo = 1e18;
    const ll N = 4e5 + 5;
    struct node
    {
        ll nxt, to;
    }e[N], e1[N];
    ll head[N], cnt, vis[N], mi[N], a[N], vi[N], mx[N];
    ll head1[N], cnt1;
    void add(ll u, ll v)
    {
        e[cnt].to=v;
        e[cnt].nxt=head[u];
        head[u]=cnt++;
    }
    void add1(ll u, ll v)
    {
        e1[cnt1].nxt=head1[u];
        e1[cnt1].to=v;
        head1[u]=cnt1++;
    }
    
    void bfs(ll n)
    {
        queue<ll> q;
        q.push(1);
        vis[1]=1;
        mi[1]=min(mi[1], a[1]);
        while(q.size())
        {
            ll u=q.front();
            q.pop();
            for(ll i=head[u]; ~i; i=e[i].nxt)
            {
                ll v=e[i].to;
                mi[v]=min(min(mi[v],a[v]), mi[u]);
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
        q.push(n);
        vi[n]=1;
        mx[n]=max(mx[n], a[n]);
        while(q.size())
        {
            ll u=q.front();
            q.pop();
            for(ll i=head1[u]; ~i; i=e1[i].nxt)
            {
                ll v=e1[i].to;
                mx[v]=max(max(mx[v],a[v]), mx[u]);
                if(!vi[v])
                {
                    vi[v]=1;
                    q.push(v);
                }
            }
        }
    }
    int main()
    {
        ll i, j, k;
        ll n, m;
        ll u, v;
        cin>>n>>m;
        for(i=1; i<=n; i++)
            cin>>a[i], mi[i]=oo, head[i]=-1, mx[i]=-oo, head1[i]=-1;
        while(m--)
        {
            cin>>u>>v>>k;
            if(k==1) add(u,v), add1(v,u);
            else add(u,v), add(v,u), add1(u,v), add1(v,u);
        }
        bfs(n);
        ll ans=0;
        for(i=1; i<=n; i++) //cout<<mi[i]<<" "<<mx[i]<<endl;
        {
            if(mi[i]!=oo && mx[i]!=-oo && mx[i]>mi[i])
                ans=max(mx[i]-mi[i], ans);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    sed 搜索并替换
    error: call of overloaded ‘sqrt(double&)’ is ambiguous
    C++数组读入MATLAB数据
    Ubuntu 18.04 安装 Octave 5.1
    Ubuntu 18.04 安装 CUDA 9.0
    LSTM 神经网络输入输出层
    tf.nn.rnn_cell.MultiRNNCell
    w = tf.Variable(<initial-value>, name=<optional-name>)
    linux下修改环境变量
    linux内核编程学习——草稿
  • 原文地址:https://www.cnblogs.com/op-z/p/11295093.html
Copyright © 2011-2022 走看看