不知哪個OJ The Number of Points in Shortest Path 最短路。。
阿新 • • 發佈:2019-04-22
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 usingnamespace 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 最短路。。