zoukankan      html  css  js  c++  java
  • Codeforces 449B_Jzzhu and Cities

    给一个无向图,外加一些特殊的连接原点的无向边。在不改变原点与所有点的最短路的情况下,最多可以删除多少条特殊边?

    首先我们把所有的边夹杂在一起。spfa跑出与所有点的最短路。

    接下来我们通过一次bfs来判断哪些特殊的边是可以删除的。这里面的原理跟迪杰斯特拉算法差不多。

    首先把原点加入队列,所有的特殊边按照长度排序,然后一直沿着非特殊边和最短的路径增广,把满足最短路条件的点都拉到队列里面来,直到队列元素为空,然后判断特殊边的最短的那一条边是否关键边,是的话就把它所连接的那个点拉到队列里面来。程序一直进行直到队列元素空且所有的特殊边都进行过判断为止。

    召唤代码君:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxn 1111111
    typedef long long ll;
    using namespace std;
    
    struct EG{
        ll v,w;
    }E[500100];
    
    ll inf=~0U>>2;
    ll to[maxn],next[maxn],c[maxn],first[maxn],edge;
    ll U[maxn],V[maxn],W[maxn],d[maxn];
    ll Q[maxn],bot,top;
    bool iq[maxn];
    ll n,m,k,tk,ans=0;
    
    bool cmp(EG e1,EG e2)
    {
        return e1.w<e2.w;
    }
    
    void addedge(ll uu,ll vv,ll ww)
    {
        edge++;
        to[edge]=vv,c[edge]=ww,next[edge]=first[uu],first[uu]=edge;
        edge++;
        to[edge]=uu,c[edge]=ww,next[edge]=first[vv],first[vv]=edge;
    }
    
    void _init()
    {
        scanf("%I64d%I64d%I64d",&n,&m,&k);
        for (ll i=1; i<=n; i++) first[i]=-1,d[i]=inf,iq[i]=false;
        edge=-1;
        for (ll i=1; i<=m; i++) scanf("%I64d%I64d%I64d",&U[i],&V[i],&W[i]),addedge(U[i],V[i],W[i]);
        tk=edge;
        for (ll i=1; i<=k; i++)
        {
            scanf("%I64d%I64d",&E[i].v,&E[i].w);
            addedge(1,E[i].v,E[i].w);
        }
    }
    
    void SPFA()
    {
        Q[bot=top=1]=1,d[1]=0,iq[1]=true;
        while (bot<=top)
        {
            ll cur=Q[bot++];
            iq[cur]=false;
            for (ll i=first[cur]; i!=-1; i=next[i])
                if (d[cur]+c[i]<d[to[i]])
                {
                    d[to[i]]=d[cur]+c[i];
                    if (!iq[to[i]]) Q[++top]=to[i],iq[to[i]]=true;
                }
        }
    }
    
    void bfs()
    {
        ll topeg=0;
        sort(E+1,E+1+k,cmp);
        for (ll i=1; i<=n; i++) iq[i]=false;
        Q[bot=top=1]=1,iq[1]=true;
        while (bot<=top || topeg<k)
        {
            if (bot<=top)
            {
                ll cur=Q[bot++];
                for (ll i=first[cur]; i!=-1; i=next[i])
                    if (i<=tk && d[cur]+c[i]==d[to[i]] && !iq[to[i]])
                        iq[to[i]]=true,Q[++top]=to[i];
            }
            else
            {
                topeg++;
                if (iq[E[topeg].v] || d[E[topeg].v]<E[topeg].w) ans++;
                    else iq[E[topeg].v]=true,Q[++top]=E[topeg].v;
            }
        }
    }
    
    int main()
    {
        inf*=inf;
        _init();
        SPFA();
        bfs();
        printf("%I64d
    ",ans);
        return 0;
    }
  • 相关阅读:
    eslint 的 env 配置是干嘛使的?
    cookie httpOnly 打勾
    如何定制 antd 的样式(theme)
    剑指 Offer 66. 构建乘积数组
    剑指 Offer 65. 不用加减乘除做加法
    剑指 Offer 62. 圆圈中最后剩下的数字
    剑指 Offer 61. 扑克牌中的顺子
    剑指 Offer 59
    剑指 Offer 58
    剑指 Offer 58
  • 原文地址:https://www.cnblogs.com/lochan/p/3858341.html
Copyright © 2011-2022 走看看