zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        return 0;
    }
  • 相关阅读:
    tomcat解压版环境变量配置
    十天冲刺(第二阶段)
    十天冲刺(第二阶段)
    十天冲刺
    十天冲刺第二阶段()
    十天冲刺(第二阶段)
    十天冲刺(第二阶段)
    十天冲刺(第一阶段)
    十天冲刺(第一阶段)
    十天冲刺(第一阶段)
  • 原文地址:https://www.cnblogs.com/oneshot/p/4121971.html
Copyright © 2011-2022 走看看