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

原文地址:https://www.cnblogs.com/WTSRUVF/p/9689559.html

时间: 2024-10-09 17:25:12

The Shortest Statement CodeForces - 1051F(待测试)的相关文章

Educational Codeforces Round 51 (Rated for Div. 2) The Shortest Statement

题目链接:The Shortest Statement 今天又在群里看到一个同学问$n$个$n$条边,怎么查询两点直接最短路.看来这种题还挺常见的. 为什么最终答案要从42个点的最短路(到$x,y$)之和,还有$x,y$到$LCA(x,y)$的距离里面取呢? 就是如果走非树边,那么一定要走42个点中的一个,不走树边,就是LCA求了. 我写的太蠢了,还写生成树,看大家都是LCA中的dfs直接标记下就行了. 验证了算法的正确,我又试了试把每条非树边只加一个点,也是AC的,其实想了想,确实正确. 1

【题解】Luogu CF1051F The Shortest Statement

原题传送门:CF1051F The Shortest Statement 题目大意,给你一个稀疏图,q次查询,查询两点之间距离 边数减点小于等于20 这不是弱智题吗,23forever dalao又开始虐题 作为蒟蒻的我只能在一旁出售烤绿鸟和main包,和大家一起吃西瓜 仔细想想,这题的确是很弱智 先随便找一个生成树,这样就能跑lca了 剩下的几条边的端点跑一下SPFA堆优化dij,用于特判,SPFA已经死了 查询先用lca算一下距离,再暴力枚举这40个端点到两点的距离值和(最多) 就这样完了,

Berland and the Shortest Paths CodeForces - 1005F(最短路树)

最短路树就是用bfs走一遍就可以了 d[v] = d[u] + 1 表示v是u的前驱边 然后遍历每个结点 存下它的前驱边 再用dfs遍历每个结点 依次取每个结点的某个前驱边即可 #include <bits/stdc++.h> #define mem(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 1e6+10, INF = 0x7fffffff; int n, m, k, cnt; int head[ma

CF1051F The Shortest Statement

题目大意:给定一张\(n\)个点\(m\)条有权边的无向联通图,\(q\)次询问两点间的最短路 \(n\le100000\),\(m\le100000\),\(1\le100000\),\(m\)-\(n\le20\). 输入样例#1: 3 3 1 2 3 2 3 1 3 1 5 3 1 2 1 3 2 3 输出样例#1: 3 4 1 输入样例#2: 8 13 1 2 4 2 3 6 3 4 1 4 5 12 5 6 3 6 7 8 7 8 7 1 4 1 1 8 3 2 6 9 2 7 1 4

jdbc:关于junit测试No tests found matching

当被测试的方法中含有以[@Test]标记的被调用的方法方法时,就会报No tests found matching... from [email protected]的错误,将被调用的方法的[@Test]去掉即可. @Test public void testSatement(){  Connection connection=null;  Statement statement=null;  ResultSet resultSet=null;  try {   //1.获取数据库连接   co

MySQL5.7—在线DDL总结

---切记:DDL操作要在业务低峰期进行 1.MySQL各版本,对于DDL的处理方式是不同的,主要有三种: ①:Copy Table方式: 这是InnoDB最早支持的方式.顾名思义,通过临时表拷贝的方式实现的.新建一个带有新结构的临时表,将原表数据全部拷贝到临                    时表,然后Rename,完成创建操作.这个方式过程中,原表是可读的,不可写.但是会消耗一倍的存储空间. ②:Inplace方式:这是原生MySQL 5.5,以及innodb_plugin中提供的方式.

SQLite在多线程环境下的应用

这几天研究了一下SQLite这个嵌入式数据库在多线程环境下的应用,感觉里面的学问还挺多,于是就在此分享一下. AD: 2014WOT全球软件技术峰会北京站 课程视频发布 先说下初衷吧,实际上我经常看到有人抱怨SQLite不支持多线程.而在iOS开发时,为了不阻塞主线程,数据库访问必须移到子线程中.为了解决这个矛盾,很有必要对此一探究竟. 关于这个问题,最权威的解答当然是SQLite官网上的“Is SQLite threadsafe?”这个问答. 简单来说,从3.3.1版本开始,它就是线程安全的了

使用JDBC向数据库中插入一条数据(第一次修改版)

增加了一个Tools类,放了一些常用的工具 package com.JDBC.java; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /**

Alex 的 Hadoop 菜鸟教程: 第11课 Hive的Java调用

声明 本文基于Centos 6.x + CDH 5.x 说到Hive就一定要说到写程序的时候怎么调用Hive.以下我通过一个例子说明如果通过java来调用hive查询数据 数据准备 建立一个文本文件叫 a.txt,内容是 1,terry 2,alex 3,jimmy 4,mike 5,kate 并上传到hive服务器的  /data/ 目录下 JDBC调用方法 加载Driver 加载driver (只说hive2的jdbc) Class.forName("org.apache.hive.jdbc