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\n",ans);
    return 0;
}
posted @ 2014-07-21 14:21  092000  阅读(1375)  评论(0编辑  收藏  举报