木子亚日乀  

题意:n个点,n-1条边,组成一个无向的联通图,然后给出q和k,q次询问,每次给出两个点,问这两个点之间的最短距离但必须经过k点。

思路:我当时是用优化的Dijkstra写的(当天刚学的),求出k点到各点的最短距离,跑了160+ms,其实用搜索写更快,组里的几个大佬都用搜索写的,我在搜索这方面还是比较弱的。还要多练练。然后今天早上用搜索写了一下,跑了60+ms,并且内存用的也很小。

题目链接:http://abc070.contest.atcoder.jp/tasks/abc070_d

Dijkstra优先队列优化代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define ll long long
const ll INF=1e15+10;
#define MAX 100005
typedef pair<ll,ll> p;
struct Edge{
    ll to;
    ll cost;
    Edge(ll to,ll cost):to(to),cost(cost){}
};
vector<Edge> edge[MAX*100];
ll dis[MAX];
ll u,v,w;
ll n,q,x;
void Dijkstra(int s)
{
    priority_queue<p,vector<p>,greater<p> > que;
    fill(dis+1,dis+n+1,INF);
    dis[s]=0;
    que.push(p(0,s));
    while(!que.empty())
    {
        p P=que.top();
        que.pop();
        v=P.second;
        if(dis[v]<P.first)
            continue;
        for(ll i=0;i<edge[v].size();i++)
        {
            Edge e=edge[v][i];
        if(dis[e.to]>dis[v]+e.cost)
        {
            dis[e.to]=dis[v]+e.cost;
            que.push(p(dis[e.to],e.to));
        }
        }
    }
}
int main()
{
    scanf("%lld",&n);
    for(ll i=1;i<=n-1;i++)
    {
        scanf("%lld%lld%lld",&u,&v,&w);
        edge[u].push_back(Edge(v,w));
        edge[v].push_back(Edge(u,w));
    }
    scanf("%lld%lld",&q,&x);
    Dijkstra(x);
    for(int i=0;i<q;i++)
    {
        scanf("%lld%lld",&u,&v);
        printf("%lld\n",dis[u]+dis[v]);
    }
    return 0;
}

 

DFS搜索:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 100005
#define ll long long
struct Edge{
    ll to;
    ll next;
    ll cost;
};
Edge edge[MAX*2];
ll head[MAX];
ll dis[MAX];
void DFS(ll u,ll v,ll w)
{
    dis[u]=w;
    for(ll i=head[u];i!=-1;i=edge[i].next)
    {
        ll to=edge[i].to;
        if(to==v)
            continue;
        DFS(to,u,w+edge[i].cost);
    }
    return ;
}
int main()
{
    ll n,u,v,w,q,k;
    scanf("%lld",&n);
    ll cnt=0;
    memset(head,-1,sizeof(head));
    for(ll i=1;i<=n-1;i++)
    {
        scanf("%lld%lld%lld",&u,&v,&w);
        edge[cnt].to=v;
        edge[cnt].cost=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
        edge[cnt].to=u;
        edge[cnt].cost=w;
        edge[cnt].next=head[v];
        head[v]=cnt++;
    }
    scanf("%lld%lld",&q,&k);
    DFS(k,-1,0);
    while(q--)
    {
        scanf("%lld%lld",&u,&v);
        printf("%lld\n",dis[u]+dis[v]);
    }
    return 0;
}

 

posted on 2017-09-29 19:03  木子亚日乀  阅读(232)  评论(0编辑  收藏  举报