zoukankan      html  css  js  c++  java
  • [题解](最短路)最短路点数

    P2510 -- The Number of Points in Shortest Path

    时间限制:1000MS      内存限制:131072KB   无   无

    题目描述(points.cpp)

    一张图有n个点,由m条带权无向边构成。对于两个点a,b你需要求出所有可能出现在a,b间最短路径上的点(包括a,b

    输入格式(points.in)

    第一行n,m表示n个点,m条边

    接下来m行,每行3个数a,b,v表示a,b之间有条边权为v的边

    接下来一个数q,表示询问的个数

    接下来q行,每行两个数a,b,表示询问a,b

    输出格式(points.out)

    对于每个询问,输出a,b之间最短路径上的点的总个数

    样例输入

    5 6

    1 2 1

    1 3 1

    2 3 1

    2 4 1

    3 5 1

    4 5 1

    3

    2 5

    5 1

    2 4

    样例输出

    4

    3

    2

    数据规模与约定

    对于10%的数据,n≤10,

    对于50%的数据,n≤100,

    对于所有的数据,n≤1000,m≤min(n⋅n/2,10000),q≤50001≤v≤10000

    注意:由于ab的最短路可能不止一条,所以所有可能出现在各种最短路上的点都要计入答案!!


     

    考試題,當時想著和最短路計數一樣dp來著,結果哦顯然掛了,雖然我還是覺得dp也行

    其實最暴力的方法應該是Floyd,對於每個詢問ans=sigma(d[a][k]+d[k][b]==d[a][b]) (1<=k<=n)

    但是卡不過,於是對每個點跑一個spfa,複雜度O(km),k為2~3,所以可以卡過

     

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    const int maxm=10010;
    int n,m,qq;
    int d[maxn][maxn],v[maxn];
    struct node{
        int v,w,nxt;
    }e[maxm*2];
    int head[maxn],cnt;
    void add(int u,int v,int w){
        e[++cnt].v=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
    }
    void floyd(){
        for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
    }
    void spfa(int s){
        memset(v,0,sizeof(v));
        queue<int>q;
        d[s][s]=0;v[s]=1;q.push(s);
        while(!q.empty()){
            int x=q.front();q.pop();v[x]=0;
            for(int i=head[x];i;i=e[i].nxt){
                int y=e[i].v,z=e[i].w;
                if(d[s][y]>d[s][x]+z){
                    d[s][y]=d[s][x]+z;
                    if(!v[y])q.push(y),v[y]=1;
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        memset(d,0x3f,sizeof(d));
        for(int i=1,u,v,w;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);add(v,u,w);
        }
        for(int i=1;i<=n;i++)spfa(i);
        scanf("%d",&qq);
        for(int i=1,a,b;i<=qq;i++){
            scanf("%d%d",&a,&b);
            int ans=0;
            for(int j=1;j<=n;j++)
            if(d[a][j]+d[j][b]==d[a][b])ans++;
            printf("%d
    ",ans);
        }
    }

     

     

     

     

     

     

     

  • 相关阅读:
    js 实现继承的6种方式(逐渐优化)
    http2.0 特性
    http 206请求
    http put post请求区别
    stopPropagation 和stopImmediatePropagation区别
    JavaScript事件流
    BFC特性 形成BFC
    元素高度、宽度获取 style currentStyle getComputedStyle getBoundingClientRect
    三栏布局解决方案
    jquery vue 框架区别
  • 原文地址:https://www.cnblogs.com/superminivan/p/10751472.html
Copyright © 2011-2022 走看看