题目:

为了随时与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;
}
View Code

相关文章: