题目:
为了随时与rainbow快速交流,Freda制造了两部传呼机。Freda和rainbow所在的地方有N座房屋、M条双向光缆。每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传递,并且传呼机的信号从光缆的其中一端传递到另一端需要花费t单位时间。现在Freda要进行Q次试验,每次选取两座房屋,并想知道传呼机的信号在这两座房屋之间传递至少需要多长时间。Freda和rainbow简直弱爆了有木有T_T,请你帮帮他们吧……
N座房屋通过光缆一定是连通的,并且这M条光缆有以下三类连接情况:
A:光缆不形成环,也就是光缆仅有N-1条。
B:光缆只形成一个环,也就是光缆仅有N条。
C:每条光缆仅在一个环中
颂芬数据占10%,2<=N<=1000,N-1<=M<=1200。
A类数据占30%,M=N-1。
B类数据占50%,M=N。
C类数据占10%,M>N。
对于100%的数据,2<=N<=10000,N-1<=M<=12000,Q=10000,1<=x,y<=N,1<=t<32768。
分析:
(对于直接想要AC的人,可以直接忽略此部分)
可以看到:对于10%的数据,可以简简单单跑一个SPFA,(但一定要注意细节,严格按照模板来),下面给出10分的代码(通往AC的路是循序渐进的):
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; struct point { int to,nxt,w; }edge[52010]; int n,m,Q,a,b,ww,cnt=0; int head[52010],vis[52010]; long long dis[22010]; void init() { memset(head,0,sizeof(head)); cnt=0; } void add(int u,int v,int wei) { cnt++; edge[cnt].to=v; edge[cnt].nxt=head[u]; edge[cnt].w=wei; head[u]=cnt; } void spfa(int st) { int fron=0,tail=1; int q[120000]; memset(vis,0,sizeof(vis)); memset(dis,0x7f,sizeof(dis)); vis[st]=1; dis[st]=0; q[1]=st; do { fron++; int tt=q[fron]; vis[tt]=0; for(int i=head[tt];i;i=edge[i].nxt) { int v=edge[i].to; if(dis[v]>dis[tt]+edge[i].w) { dis[v]=dis[tt]+edge[i].w; if(!vis[v]) { vis[v]=1; tail++; q[tail]=v; } } } }while(fron!=tail); } int main() { cin>>n>>m>>Q; init(); for(int i=1;i<=m;i++) { cin>>a>>b>>ww; add(a,b,ww); add(b,a,ww); } while(Q--) { cin>>a>>b; spfa(a); cout<<dis[b]<<endl; } return 0; }