uva 11354 Bond

/*
题目大意 给一个双向连通的图,回答若干个询问,每个询问包含一个起点s和一个终点t,
要求找到一个从s到t的路,使得路径所有边的最大危险系数最小

本题为瓶颈路
要支持快速询问,把信息组织成某种易于查询的结构

先求出最小生成树,快速求出maxcost[i][j]

*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 50050;
const int maxm = 100010;
const int logmaxn = 20;
const int INF = 1000000000;

struct Edge
{
    int from,to,w;
    Edge(const int& from = 0,const int& to = 0,const int& w = 0):from(from),to(to),w(w) {}
    Edge(const Edge& rsh)
    {
        this->from = rsh.from;
        this->to = rsh.to;
        this->w = rsh.w;
    }
    bool operator < (const Edge& rsh ) const
    {
        return this->w < rsh.w;
    }
};

int n,m;
int root[maxn];
vector<Edge> edges;
vector<int> G[maxn],C[maxn];

// 并查集
void init_set(int n)
{
    for(int i = 0 ; i < n ; i++)
    {
        root[i] = i;
        G[i].clear();
        C[i].clear();
    }
}

int find_set(int x)
{
    if(x != root[x])
    {
        root[x] = find_set(root[x]);
    }
    return root[x];
}

void union_set(int a,int b)
{
    int x = find_set(a);
    int y = find_set(b);
    if(x != y)
    {
        root[x] = y;
    }
}

void MST()
{
    sort(edges.begin(),edges.end());
    for(int i = 0 ; i < edges.size() ; i++)
    {
        int from = edges[i].from;
        int to = edges[i].to;
        int w = edges[i].w;
        if(find_set(from) != find_set(to))
        {
            union_set(from,to);
            G[from].push_back(to);
            C[from].push_back(w);
            G[to].push_back(from);
            C[to].push_back(w);
        }
    }
}

struct LCA
{
    int n;
    int fa[maxn];//i的父亲编号
    int cost[maxn];//i到父亲节点的距离
    int L[maxn];//i节点的深度
    int anc[maxn][logmaxn]; //节点i到第2^j级祖先的编号
    int maxcost[maxn][logmaxn];//节点i与第2^j级祖先之间的路径上的最大权值

    void preprocess() //预处理
    {

        for(int i = 0 ; i < n ; i++)
        {
            anc[i][0] = fa[i];
            maxcost[i][0] = cost[i];
            for(int j = 1 ; (1 << j) < n ; j++)
            {
                anc[i][j] = -1;
            }
        }

        for(int j = 1 ; (1 << j) < n ; j++)
        {
            for(int i = 0 ; i < n ; i++)
            {
                if(anc[i][j-1] != -1)
                {
                    int a = anc[i][j-1];
                    anc[i][j] = anc[a][j-1];
                    maxcost[i][j] = max(maxcost[i][j-1],maxcost[a][j-1]);
                }
            }
        }
    }

    int query(int p,int q)
    {
        int log;
        if( L[p] < L[q]) swap(p,q);
        for(log = 1 ; (1 << log) <= L[p] ; log++);
        log--;

        int ans = -INF;
        for(int i = log ; i >= 0 ; i--)
        {
            if(L[p] - (1<<i) >= L[q])
            {
                ans = max(ans,maxcost[p][i]);
                p = anc[p][i];
            }
        }

        if(p == q) // LCA 为p
        {
            return ans;
        }

        for(int i = log ; i >= 0 ; i--)
        {
            if(anc[p][i] != -1 && anc[p][i] != anc[q][i])
            {
                ans = max(ans,maxcost[p][i]);
                p = anc[p][i];
                ans = max(ans,maxcost[q][i]);
                q = anc[q][i];
            }
        }

        ans = max(ans,cost[p]);
        ans = max(ans,cost[q]);
        return ans;// LCA 为fa[p]也等于fa[q]
    }
};

LCA solver;


void dfs(int u,int fa,int level)
{
    solver.L[u] = level;
    for(int i = 0 ; i < G[u].size() ; i++)
    {
        int v = G[u][i];
        if(v != fa)
        {
            solver.fa[v] = u;
            solver.cost[v] = C[u][i];
            dfs(v,u,level+1);
        }
    }
}

void init()
{
    edges.clear();
    init_set(n);
}

int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int kcase = 0;
    while(scanf("%d %d",&n,&m) != EOF)
    {
        init();
        int from,to,w;
        for(int i = 0 ; i < m ; i++)
        {
            scanf("%d %d %d",&from,&to,&w);
            from--;
            to--;
            edges.push_back(Edge(from,to,w));
        }
        MST();
        solver.n = n;
        dfs(0,-1,0);

        solver.preprocess();
        if(++kcase != 1) printf("\n");
        int Q;
        scanf("%d",&Q);
        while(Q--)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            printf("%d\n",solver.query(x-1,y-1));
        }
    }
    return 0;
}

《餐馆点餐管理系统——基于Java和MySQL的课程设计解析》 在信息技术日益发达的今天,餐饮行业的数字化管理已经成为一种趋势。本次课程设计的主题是“餐馆点餐管理系统”,它结合了编程语言Java和数据库管理系统MySQL,旨在帮助初学者理解如何构建一个实际的、具有基本功能的餐饮管理软件。下面,我们将深入探讨这个系统的实现细节及其所涉及的关键知识点。 我们要关注的是数据库设计。在“res_db.sql”文件中,我们可以看到数据库的结构,可能包括菜品表、订单表、顾客信息表等。在MySQL中,我们需要创建这些表格并定义相应的字段,如菜品ID、名称、价格、库存等。此外,还要设置主键、外键来保证数据的一致性和完整性。例如,菜品ID作为主键,确保每个菜品的唯一性;订单表中的顾客ID和菜品ID则作为外键,与顾客信息表和菜品表关联,形成数据间的联系。 接下来,我们来看Java部分。在这个系统中,Java主要负责前端界面的展示和后端逻辑的处理。使用Java Swing或JavaFX库可以创建用户友好的图形用户界面(GUI),让顾客能够方便地浏览菜单、下单。同时,Java还负责与MySQL数据库进行交互,通过JDBC(Java Database Connectivity)API实现数据的增删查改操作。在程序中,我们需要编写SQL语句,比如INSERT用于添加新的菜品信息,SELECT用于查询所有菜品,UPDATE用于更新菜品的价格,DELETE用于删除不再提供的菜品。 在系统设计中,我们还需要考虑一些关键功能的实现。例如,“新增菜品和价格”的功能,需要用户输入菜品信息,然后通过Java程序将这些信息存储到数据库中。在显示所有菜品的功能上,程序需要从数据库获取所有菜品数据,然后在界面上动态生成列表或者表格展示。同时,为了提高用户体验,可能还需要实现搜索和排序功能,允许用户根据菜品名称或价格进行筛选。 另外,安全性也是系统设计的重要一环。在连接数据库时,要避免SQL注入攻击,可以通过预编译的PreparedStatement对象来执行SQL命令。对于用户输入的数据,需要进行验证和过滤,防止非法字符和异常值。 这个“餐馆点餐管理系统”项目涵盖了Java编程、数据库设计与管理、用户界面设计等多个方面,是一个很好的学习实践平台。通过这个项目,初学者不仅可以提升编程技能,还能对数据库管理和软件工程有更深入的理解。在实际开发过程中,还会遇到调试、测试、优化等挑战,这些都是成长为专业开发者不可或缺的经验积累
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值