1. 程式人生 > >不知哪個OJ The Number of Points in Shortest Path 最短路。。

不知哪個OJ The Number of Points in Shortest Path 最短路。。

mem ace false cst 限制 dijkstra continue 短路徑 air

emm..我佛了。。。spafa為何這麽快。。。這。。QAQ


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之間最短路徑上的點的總個數

數據規模與約定

對於10%的數據,n≤10,

對於50%的數據,n≤100,

對於所有的數據,n≤1000,m≤min(n⋅n/2,10000),q≤5000,1≤v≤10000

註意:由於a到b的最短路可能不止一條,所以所有可能出現在各種最短路上的點都要計入答案!!

考試時floyed硬剛,只有50分。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#define R register int
using
namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,m,q; int e[1010][1010]; signed main() { n=g(),m=g(); memset(e,0x3f,sizeof(e)); for(R i=1,u,v;i<=m;++i) u=g(),v=g(),e[u][v]=e[v][u]=g();
for(R i=1;i<=n;++i) e[i][i]=0; for(R k=1;k<=n;++k) for(R i=1;i<=n;++i) for(R j=1;j<=n;++j) e[i][j]=min(e[i][j],e[i][k]+e[k][j]); q=g(); for(R i=1,u,v;i<=q;++i) { u=g(),v=g(); R cnt=0; for(R i=1;i<=n;++i) if(e[u][i]+e[i][v]==e[u][v]) ++cnt; printf("%d\n",cnt); } }

考完試看題解:

spafa?!

what?!?!?!?

周一,我忽然覺得dijkstra也可以卡過(mlogn,差不多1E+8)。。。然鵝。。。50分。。。

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define R register int
const int N=1010,M=10010;
using namespace std;
inline int g() {
    R ret=0; register char ch; while(!isdigit(ch=getchar())); 
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
}
int n,m,t,cnt=1;
int vr[M<<1],nxt[M<<1],w[M<<1],fir[N],d[N][N];
bool vis[N];
priority_queue<pair<int,int> >q;
inline void add(int u,int v,int ww) {vr[++cnt]=v,w[cnt]=ww,nxt[cnt]=fir[u],fir[u]=cnt;}
signed main() {
    freopen("points.in","r",stdin);
    freopen("points.out","w",stdout);
    n=g(),m=g();
    for(R i=1,u,v,w;i<=m;++i) u=g(),v=g(),w=g(),add(u,v,w),add(v,u,w);
    memset(d,0x3f,sizeof(d));
    for(R i=1;i<=n;++i) { memset(vis,0,sizeof(vis));
        q.push(make_pair(0,i)),vis[i]=false; d[i][i]=0;
        while(q.size()) {
            R u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true;
            for(R j=fir[u];j;j=nxt[j]) { R v=vr[j];
                if(d[i][v]>d[i][u]+w[j]) d[i][v]=d[i][u]+w[j],q.push(make_pair(-d[i][v],v));
            }
        }
    } t=g();
    for(R i=1,u,v;i<=t;++i) {
        u=g(),v=g(); R ans=0;
        for(R j=1;j<=n;++j) if(d[u][j]+d[j][v]==d[u][v]) ++ans;
        printf("%d\n",ans);
    }
}

好吧。。上spafa。。。what。。。竟然A了。。。我佛了。。。

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define R register int
using namespace std;
const int N=1010,M=10010;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m,t,cnt=1;
int vr[M<<1],nxt[M<<1],w[M<<1],fir[N],d[N][N];
bool vis[N];
queue<int> q;
inline void add(int u,int v,int ww) {vr[++cnt]=v,w[cnt]=ww,nxt[cnt]=fir[u],fir[u]=cnt;}
signed main() {
    freopen("points.in","r",stdin);
    freopen("points.out","w",stdout);
    n=g(),m=g();
    for(R i=1,u,v,w;i<=m;++i) u=g(),v=g(),w=g(),add(u,v,w),add(v,u,w);
    memset(d,0x3f,sizeof(d));
    for(R i=1;i<=n;++i) {
        d[i][i]=0; q.push(i),vis[i]=true;
        while(q.size()) {
            R u=q.front(); q.pop(); vis[u]=false;
            for(R j=fir[u];j;j=nxt[j]) { R v=vr[j];
                if(d[i][v]>d[i][u]+w[j]) {
                    d[i][v]=d[i][u]+w[j];
                    if(!vis[v]) vis[v]=true,q.push(v);
                }
            }
        }
    } t=g();
    for(R i=1,u,v;i<=t;++i) {  R ans=0;
        u=g(),v=g();
        for(R j=1;j<=n;++j) if(d[u][j]+d[j][v]==d[u][v]) ++ans;
        printf("%d\n",ans);
    }
}

好吧。。。。spafa好。。。(嗎?重新認知。。


2019.04.22

不知哪個OJ The Number of Points in Shortest Path 最短路。。