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;
}
时间: 2024-12-06 13:19:02

codeforces257 div2 D最短路条数的相关文章

关于 最短路条数 和 边不可重复最短路条数问题 /hdu3599(边不可重复最短路)

原先一直在做一道省赛题,由于题意错误理解成球最短路条数,误打误撞敲了最短路条数,又发现hdu3599(多校)求边不可重复最短路条数.下面说说俩种问题解法: 最短路条数: 求一个图一共一几条最短路径,思路:先从终点跑一边最短路,记录终点到到所有点最短距离(d[i]),然后从起点出发,dfs 按d[i]走(必是最短路径),一句话:我到终点的最短路条数=我的所有孩子到终点的最短路条数之和,这样只需一遍即可.这不知道是不是叫记忆化搜索? 边不可重复最短路径条数:(最短路+建新图之最大流) hdu3599

【PAT】Emergency(最短路条数-SPFA)

[PAT]Emergency(最短路条数-SPFA) As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road betw

POJ 3463 最(次)短路条数

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9497   Accepted: 3340 Description Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. O

HDU1688 Sightseeing(SPFA 求最短路与次短路的路径条数)可用作模板

Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 718    Accepted Submission(s): 293 Problem Description Tour operator Your Personal Holiday organises guided bus trips across the Bene

hdu 1688 Sightseeing【最短路,次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:求最短路和次短路条数如果次短路长度=最短路长度+1 这输出次短路条数+最短路条数,否则输出最短路条数 分析:这是到模版题,献上模版: #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<

HDU 3191 次短路长度和条数

http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html http://blog.csdn.net/me4546/article/details/6584448 维护最短路长度d[i][0]和次短路d[i][1],最短路条数dp[i][0]和次短路dp[i][1] #include <iostream> #include <string> #include <cstring> #include <cs

eoj1818 dijkstra求最短路及其条数

求出有n(1 < n <= 100)个结点有向图中,结点1到结点n的最短路径,以及最短路径的条数. Input 第一行有2个整数n和m( 0 < m < 3000),接下来m行每行有三个整数u,v,w结点u到v之间有一条权为w的边(w<100000). Output 输出只有一行,为结点1到结点n之间的最短路径及其条数(用空格隔开),如果1到n之间不存在路径,输出 -1 0. Sample Input 3 3 1 2 10 2 3 15 1 3 25 Sample Outpu

POJ_3463_Sightseeing(最短路/次短路条数)

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7421   Accepted: 2659 Description Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. O

HDU 1688 Sightseeing 【输出最短路+次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题目大意:给n个点,m条有向边.再给出起点s, 终点t.求出s到t的最短路条数+次短路条数. 思路: 1.最短路和次短路是紧密相连的,在最短路松弛操作中,当我们找到一条更短的路径,也就意味着之前的路径不再是最短路,而成为了次短路,利用这个关系可以实现状态的转移. 2.好久没写优先队列了,都忘记了加个 priority_queue, 这样才能写重载,才能排序. 注释在代码里: 1 #includ