codeforces257 div2 D最短路条数

题意:

给一个无向图,总共有 n个点,m+k条边,给定点所连的k条边可以选择删除

问最多删除多少条可以保持该定点到其他点的最短路不变

题解:

从定点出发做单元最短路

首先如果定点到某个点的最短路小于 可删边的长度,则肯定可以删除

此外如果最短路与可删边长度相等,而且最短路条数大于1,肯定也可以删除

所以在做最短路的时候需要记录一下条数

//同时还会有重边,也要注意处理

ps...这题sxbk的把普通的spfa 都卡了。。加了slf优化才过,据说dij可以轻松过。。不过我没试2333

以后写spfa还是都写deque版的吧= =!

代码:

#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int inf =1000000001;
struct edge
{
    int from,to,w,next;
}e[800010];
int head[100010];
int vis[100010];
int dist[100010];
int vi[100010];
int hs[100010];
int n,m,t;
void add(int i,int j,int w)
{
    e[t].from=i;
    e[t].to=j;
    e[t].w=w;
    e[t].next=head[i];
    head[i]=t++;
    return ;
}
void spfa(int s)
{
    deque <int> q;
    for(int i=1;i<=n;i++)
        dist[i]=inf;
    memset(vis,false,sizeof(vis));
    q.push_back(s);
    dist[s]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop_front();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=e[i].next)
        {

            int v=e[i].to;
            if(dist[v]>=dist[u]+e[i].w)
            {
                dist[v]=dist[u]+e[i].w;
                if(dist[v]==hs[v])
                    vi[v]++;
                else if(dist[v]<hs[v])
                    vi[v]=2;
                if(!vis[v])
                {
                    vis[v]=true;
                    if(!q.empty()&&dist[v]<dist[q.front()])  //spfa的slf优化
                        q.push_front(v);
                    else
                        q.push_back(v);
                }
            }
        }
    }
}
int main()
{
    int a,b,c,k;
    scanf("%d%d%d",&n,&m,&k);
    t=0;
    memset(head,-1,sizeof(head));
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
        add(b,a,c);
    }
    int ans=0;
    while(k--)
    {
        scanf("%d%d",&b,&c);
        if(hs[b]==0)
        {
            hs[b]=c;
            add(1,b,c);
            add(b,1,c);
        }
        else                 //处理重边
        {
            ans++;
            if(c<hs[b])
            {
                hs[b]=c;
                add(1,b,c);
                add(b,1,c);
            }
        }
    }
    spfa(1);
    for(int i=2;i<=n;i++)
    {
        if(vi[i]>1)
            ans++;
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2014-11-25 21:27  PlasticSpirit  阅读(204)  评论(0编辑  收藏  举报