NOIP2013D1T3货车运输(最大生成树+倍增lca)

传送门

这道题,先用kruskal求一遍图中的最大生成树。

然后,倍增求lca,求lca的同时求出边权的最小值。

#include <cstring>
#include <cstdio>
#include <algorithm>

int n, m, cnt, q, t, k;
int f[10001], head[100001], p[10001][21], minn[10001][21], deep[10001];
bool vis[10001];
struct node
{
    int x, y, z;
}tree[100001];
struct Node
{
    int next, to, val;
}edge[100001];

inline void add(int a, int b, int c)
{
    edge[cnt].val = c;
    edge[cnt].to = b;
    edge[cnt].next = head[a];
    head[a] = cnt++;
}

inline int father(int a)
{
    return a == f[a] ? a : f[a] = father(f[a]);
}

inline bool cmp(node a, node b)
{
    return a.z > b.z;
}

void kruskal()
{
    int i;
    for(i = 1; i <= m; i++)    scanf("%d %d %d", &tree[i].x, &tree[i].y, &tree[i].z);
    for(i = 1; i <= n; i++) f[i] = i;
    std::sort(tree + 1, tree + m + 1, cmp);
    for(i = 1; i <= m; i++)
    {
        int fa = father(tree[i].x), fb = father(tree[i].y);
        if(fa != fb)
        {
            f[fa] = fb;
            add(tree[i].x, tree[i].y, tree[i].z);
            add(tree[i].y, tree[i].x, tree[i].z);
        }
        if(k == n - 1) break;
    }
}

void dfs(int i)
{
    int j;
    vis[i] = 1;
    for(j = head[i]; j != -1; j = edge[j].next)
     if(!vis[edge[j].to])
     {
         deep[edge[j].to] = deep[i] + 1;
         p[edge[j].to][0] = i;
         minn[edge[j].to][0] = edge[j].val;
         dfs(edge[j].to);
     }
}

void init()
{
    int i, j;
    for(j = 1; (1 << j) <= n; j++)
     for(i = 1; i <= n; i++)
     {
         p[i][j] = p[p[i][j - 1]][j - 1];
         minn[i][j] = std::min(minn[i][j - 1], minn[p[i][j - 1]][j - 1]);
     }
}

int lca(int a, int b)
{
    int i, j, ret = 707406378;
    if(deep[a] < deep[b]) std::swap(a, b);
    for(i = 0; (1 << i) <= deep[a]; i++);
    i--;
    for(j = i; j >= 0; j--)
     if(deep[a] - (1 << j) >= deep[b])
     {
         ret = std::min(ret, minn[a][j]);
         a = p[a][j];
     }
    if(a == b) return ret;
    for(j = i; j >= 0; j--)
     if(p[a][j] != p[b][j])
     {
         ret = std::min(ret, std::min(minn[a][j], minn[b][j]));
         a = p[a][j];
         b = p[b][j];
     }
    ret = std::min(ret, std::min(minn[a][0], minn[b][0]));
    return ret;
}

int main()
{
    int i, j, x1, y1;
    scanf("%d %d", &n, &m);
    memset(head, -1, sizeof(head));
    //memset(minn, 127 / 3, sizeof(minn));
    kruskal();
    for(i = 1; i <= n; i++)
     if(!vis[i])
     {
         deep[i] = 1;
         dfs(i);
     }
    init();
    scanf("%d", &q);
    for(i = 1; i <= q; i++)
    {
        scanf("%d %d", &x1, &y1);
        if(father(x1) != father(y1)) printf("-1\n");
        else printf("%d\n", lca(x1, y1));
     }
    return 0;

}
View Code

 

换了写法

惨啊,

i >= 0 我居然nc的用 i 代替

应该是 i >= 1 用 i 代替

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 const int MAXN = 10001, MAXM = 50001, INF = 707406378;
  6 int n, m, q, cnt, tot;
  7 int head[MAXM], to[MAXM << 1], next[MAXM << 1], val[MAXM << 1];
  8 int f1[MAXN], f[MAXN][21], min[MAXN][21], deep[MAXN];
  9 
 10 struct node
 11 {
 12     int x, y, z;
 13 }p[MAXM];
 14 
 15 inline bool cmp(node a, node b)
 16 {
 17     return a.z > b.z;
 18 }
 19 
 20 inline void add(int x, int y, int z)
 21 {
 22     to[cnt] = y;
 23     val[cnt] = z;
 24     next[cnt] = head[x];
 25     head[x] = cnt++;
 26 }
 27 
 28 inline int find(int x)
 29 {
 30     return x == f1[x] ? x : f1[x] = find(f1[x]);
 31 }
 32 
 33 inline int Min(int x, int y)
 34 {
 35     return x < y ? x : y;
 36 }
 37 
 38 inline void swap(int &x, int &y)
 39 {
 40     x ^= y ^= x ^= y;
 41 }
 42 
 43 inline void dfs(int u)
 44 {
 45     int i, v;
 46     deep[u] = deep[f[u][0]] + 1;
 47     for(i = 0; f[u][i]; i++)
 48         f[u][i + 1] = f[f[u][i]][i],
 49         min[u][i + 1] = Min(min[u][i], min[f[u][i]][i]);
 50     for(i = head[u]; i ^ -1; i = next[i])
 51     {
 52         v = to[i];
 53         if(!deep[v])
 54         {
 55             f[v][0] = u;
 56             min[v][0] = val[i];
 57             dfs(v);
 58         }
 59     }
 60 }
 61 
 62 inline int lca(int x, int y)
 63 {
 64     int i, ans = INF;
 65     if(deep[x] < deep[y]) swap(x, y);
 66     for(i = 20; i >= 0; i--)
 67         if(deep[f[x][i]] >= deep[y])
 68             ans = Min(ans, min[x][i]), x = f[x][i];
 69     if(x == y) return ans == INF ? -1 : ans;
 70     for(i = 20; i >= 0; i--)
 71         if(f[x][i] ^ f[y][i])
 72             ans = Min(ans, min[x][i]),
 73             ans = Min(ans, min[y][i]),
 74             x = f[x][i], y = f[y][i];
 75     ans = Min(ans, min[x][0]);
 76     ans = Min(ans, min[y][0]);
 77     return ans == INF ? -1 : ans;
 78 }
 79 
 80 int main()
 81 {
 82     //freopen("truck.in", "r", stdin);
 83     //freopen("truck.out", "w", stdout);
 84     int i, x, y, fx, fy;
 85     scanf("%d %d", &n, &m);
 86     memset(head, -1, sizeof(head));
 87     memset(min, 127 / 3, sizeof(min));
 88     for(i = 1; i <= m; i++) scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].z);
 89     std::sort(p + 1, p + m + 1, cmp);
 90     for(i = 1; i <= n; i++) f1[i] = i;
 91     for(i = 1; i <= m; i++)
 92     {
 93         fx = find(p[i].x);
 94         fy = find(p[i].y);
 95         if(fx ^ fy)
 96         {
 97             f1[fx] = fy;
 98             tot++;
 99             add(p[i].x, p[i].y, p[i].z);
100             add(p[i].y, p[i].x, p[i].z);
101         }
102         if(tot == n - 1) break; 
103     }
104     for(i = 1; i <= n; i++)
105         if(!deep[i])
106             dfs(i);
107     scanf("%d", &q);
108     for(i = 1; i <= q; i++)
109     {
110         scanf("%d %d", &x, &y);
111         if(find(x) ^ find(y)) puts("-1");
112         else printf("%d\n", lca(x, y));
113     }
114     return 0;
115 }
View Code

 

转载于:https://www.cnblogs.com/zhenghaotian/p/6667614.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值