[Usaco2013 DEC] Vacation Planning

[题目链接]

        https://www.lydsy.com/JudgeOnline/problem.php?id=4093

[算法]

        对于k个枢纽 , 分别在正向图和反向图上跑dijkstra最短路 , 即可

        时间复杂度 : O(K(N + M) log N)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 20010
#define MAXK 210
typedef long long LL;
const LL inf = 1e15;

int n , m , k , q , tot;
int heada[MAXN] , headb[MAXN];
LL dist1[MAXK][MAXN] , dist2[MAXK][MAXN];
bool visited[MAXK][MAXN];

struct edge
{
    int to , w , nxt;
} e[MAXN << 2];

template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline void addedgea(int u , int v , int w)
{
    tot++;
    e[tot] = (edge){v , w , heada[u]};
    heada[u] = tot;
}
inline void addedgeb(int u , int v , int w)
{
    tot++;
    e[tot] = (edge){v , w , headb[u]};
    headb[u] = tot;    
}
inline void dijkstra1(int idx,int s)
{
    priority_queue< pair<int,int> > q;
    for (int i = 1; i <= n; i++) dist1[idx][i] = inf;
    dist1[idx][s] = 0;
    q.push(make_pair(0 , s));
    while (!q.empty())
    {
        int cur = q.top().second;
        q.pop();
        if (visited[idx][cur]) continue;
        visited[idx][cur] = true;
        for (int i = heada[cur]; i; i = e[i].nxt)
        {
            int v = e[i].to , w = e[i].w;
            if (dist1[idx][cur] + w < dist1[idx][v])
            {
                dist1[idx][v] = dist1[idx][cur] + w;
                q.push(make_pair(-dist1[idx][v] , v));
            }
        }
    }
}
inline void dijkstra2(int idx,int s)
{
    priority_queue< pair<int,int> > q;
    for (int i = 1; i <= n; i++) dist2[idx][i] = inf;
    dist2[idx][s] = 0;
    q.push(make_pair(0 , s));
    while (!q.empty())
    {
        int cur = q.top().second;
        q.pop();
        if (visited[idx][cur]) continue;
        visited[idx][cur] = true;
        for (int i = headb[cur]; i; i = e[i].nxt)
        {
            int v = e[i].to , w = e[i].w;
            if (dist2[idx][cur] + w < dist2[idx][v])
            {
                dist2[idx][v] = dist2[idx][cur] + w;
                q.push(make_pair(-dist2[idx][v] , v));
            }
        }
    }
}

int main()
{
    
    read(n); read(m); read(k); read(q);
    for (int i = 1; i <= m; i++)
    {
        int u , v , w;
        read(u); read(v); read(w);
        addedgea(u , v , w);
        addedgeb(v , u , w);
    }
    for (int i = 1; i <= k; i++)
    {
        int x;
        read(x);
        memset(visited[i] , false , sizeof(visited[i]));
        dijkstra1(i , x);
        memset(visited[i] , false , sizeof(visited[i]));
        dijkstra2(i , x);    
    }
    int ans1 = 0 , ans2 = 0;
    while (q--)
    {
        int x , y;
        read(x); read(y);
        LL tmp = inf;
        for (int i = 1; i <= k; i++) chkmin(tmp , 1LL * dist2[i][x] + 1LL * dist1[i][y]);
        if (tmp != inf)
                {
                        ++ans1;
                        ans2 += (LL)tmp;
                }
    }
    printf("%d
%d
" , ans1 , ans2);
    return 0;
}
原文地址:https://www.cnblogs.com/evenbao/p/9844220.html