The Shortest Statement CodeForces - 1051F(待测试)

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 2 * 1e5 + 10, INF = 0x7fffffff;
LL n, m, cnt1, cnt2, c;
LL head1[maxn], head2[maxn], f[maxn], vis[maxn], bz[maxn];
LL dis[50][maxn], d[maxn];
LL res[maxn];
vector<LL> se;
struct node
{
    LL u, v, w, next;
}Node[maxn];

struct edge
{
    LL u, v, id, next;
}Edge[maxn];

void add1_(LL u, LL v, LL w)
{
    Node[cnt1].u = u;
    Node[cnt1].v = v;
    Node[cnt1].w = w;
    Node[cnt1].next = head1[u];
    head1[u] = cnt1++;
}

void add1(LL u, LL v, LL w)
{
    add1_(u, v, w);
    add1_(v, u, w);
}

void add2_(LL u, LL v, LL id)
{
    Edge[cnt2].u = u;
    Edge[cnt2].v = v;
    Edge[cnt2].id = id;
    Edge[cnt2].next = head2[u];
    head2[u] = cnt2++;
}

void add2(LL u, LL v, LL id)
{
    add2_(u, v, id);
    add2_(v, u, id);
}

LL find(LL x)
{
    return f[x]==x?x:(f[x] = find(f[x]));
}

LL lca(LL u, LL deep, LL root)
{
    f[u] = u;
    d[u] = deep;
    vis[u] = root;  // 标记属于的树
    for(LL i=head1[u]; i!=-1; i=Node[i].next)
    {
        node e = Node[i];
        if(vis[e.v] == -1)
        {
            bz[i/2] = 1;
            lca(e.v, deep+e.w, root);
            f[e.v] = u;
        }
    }
    for(LL i=head2[u]; i!=-1; i=Edge[i].next)
    {
        edge e = Edge[i];
        if(vis[e.v] == root)   //判断另一个结点是不是和u属于一个树
        {
            LL k = find(e.v);  //寻找最近公共祖先
            res[e.id] = d[u] + d[e.v] - 2*d[k];
        }
    }
}

void spfa(LL s, LL id)
{
    for(LL i=0; i<=n; i++) dis[id][i] = INF;
    mem(vis, 0);
    queue<LL> Q;
    Q.push(s);
    vis[s] = 1;
    dis[id][s] = 0;
    while(!Q.empty())
    {
        LL u = Q.front(); Q.pop();
        vis[u] = 0;
        for(LL i=head1[u]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(dis[id][e.v] > dis[id][u] + e.w)
            {
                dis[id][e.v] = dis[id][u] + e.w;
                if(!vis[e.v])
                {
                    Q.push(e.v);
                    vis[e.v] = 1;
                }
            }
        }
    }
}

void init()
{
    mem(head1, -1);
    mem(head2, -1);
    mem(res, -1);
    mem(vis, -1);
    cnt1 = cnt2 = 0;
}

int main()
{
    cin >> n >> m;
    init();
    rap(i, 1, m)
    {
        LL u, v, w;
        scanf("%lld%lld%lld", &u, &v, &w);
        add1(u, v, w);
    }
    cin >> c;
    for(LL i=1; i<=c; i++)
    {
        LL u, v;
        scanf("%lld%lld", &u, &v);
        add2(u, v, i);
    }
    for(LL i=1; i<=n; i++)
        if(vis[i] == -1)
            lca(i, 0, i);
    mem(vis, -1);
    for(LL i=0; i<cnt1; i++)
    {
        if(!bz[i/2])
        {
            if(vis[Node[i].u] == -1) se.push_back(Node[i].u), vis[Node[i].u] = 1;
            if(vis[Node[i].v] == -1) se.push_back(Node[i].v), vis[Node[i].v] = 1;
        }
    }
    for(LL i=0; i<se.size(); i++)
    {
      //  cout << se[i] << endl;
        spfa(se[i], i);

    }

    for(LL i=1; i<=c; i++)
    {
        for(LL j=0; j<se.size(); j++)
            res[i] = min(res[i], dis[j][Edge[i*2-1].u] + dis[j][Edge[i*2-1].v]);
        printf("%lld\n", res[i]);
    }


    return 0;
}

The Shortest Statement

 CodeForces - 1051F

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9689559.html