一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先。第一次写..表示各种乱..

因为要求运输货物质量最大,所以路径一定是在最大生成树上的。然后就用LCA求两点之间的能运输的最大重量。预处理O(nlogn),查询O(logn).

----------------------------------------------------------------------------------------

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cctype>
#define rep(i,n) for(int i=0;i<n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define Rep(i,l,r) for(int i=l;i<r;i++)
#define addEdge(u,v,d) MST.edges.push_back((Edge){u,v,d})
#define jud(a,b) MST.find(a)-MST.find(b)
using namespace std;
const int maxn=10000+5,maxs=20;
const int inf=0x7fffffff;
struct Edge {
int u,v,d;
Edge(int _u,int _v,int _d):u(_u),v(_v),d(_d) {}
bool operator < (const Edge &x) const {
return d>x.d;
}
};
struct LCA {
int p[maxn][maxs];
int depth[maxn];
int d[maxn][maxs];
bool vis[maxn];
int n;
vector<int> g[maxn];
vector<Edge> edges;
void init(int _n) {
n=_n;
edges.clear();
rep(i,n) { g[i].clear(); vis[i]=false; }
}
void add(int u,int v,int d) {
edges.push_back( (Edge) {u,v,d} );
edges.push_back( (Edge) {v,u,d} );
int m=edges.size();
g[u].push_back(m-2);
g[v].push_back(m-1);
}
void dfs(int x) {
int t=1;
vis[x]=1;
while(depth[x]>=(1<<t)) {
p[x][t]=p[p[x][t-1]][t-1];
d[x][t]=min(d[x][t-1],d[p[x][t-1]][t-1]);
t++;
}
rep(i,g[x].size()) {
Edge &e=edges[g[x][i]];
if(vis[e.v]) continue;
p[e.v][0]=x;
d[e.v][0]=e.d;
depth[e.v]=depth[x]+1;
dfs(e.v);
}
}
void DFS() { rep(i,n) if(!vis[i]) { depth[i]=0; dfs(i); } }
int query(int a,int b) {
int tmp,log=1;
if(depth[a]<depth[b]) swap(a,b);
while((1<<(log+1))<=depth[a]) log++;
int ans=inf;
for(int i=log;i>=0;--i) if(depth[a]-(1<<i)>=depth[b]) {
ans=min(ans,d[a][i]);
a=p[a][i];
}
if(a==b) return ans;
for(int i=log;i>=0;--i) if(p[a][i]!=-1 && p[a][i]!=p[b][i]) {
ans=min(ans,d[a][i]); a=p[a][i];
ans=min(ans,d[b][i]); b=p[b][i];
}
return ans=min(ans,min(d[a][0],d[b][0]));
}
};
LCA lca;
  
struct KRUSKAL {
int n;
int p[maxn];
vector<Edge> edges;
void init(int _n) {
n=_n;
edges.clear();
}
int find(int x) { return x==p[x] ? x : p[x]=find(p[x]); }
void kruskal() {
rep(i,n) p[i]=i;
sort(edges.begin(),edges.end());
rep(i,edges.size()) {
Edge &e=edges[i];
int x=find(e.u),y=find(e.v);
if(x!=y) {
p[x]=y;
   lca.add(e.u,e.v,e.d);
}
}
}
};
  
KRUSKAL MST;
int read() {
char c=getchar();
int ans=0,f=1;
while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); }
while(isdigit(c)) { (ans*=10)+=c-'0'; c=getchar(); }
return f*ans;
}
   
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
int n=read(),m=read();
MST.init(n);
lca.init(n);
rep(i,m) {
int u=read(),v=read(),d=read();
addEdge(--u,--v,d);
}
MST.kruskal();
lca.DFS();
n=read();
rep(i,n) {
int a=read(),b=read();
--a; --b;
if(jud(a,b)) printf("-1\n");
else {
printf("%d\n",lca.query(a,b));
}
}
return 0;
}

----------------------------------------------------------------------------------------

3287 货车运输

2013年NOIP全国联赛提高组

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond

[NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)的更多相关文章

  1. JZOJ 3534. 【NOIP2013提高组day1】货车运输

    Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的 ...

  2. [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路

    [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路 题目大意: 对于长度为\(n(n\le10^5)\)的非负数列\(A\),每次可以选取一个区间\(-1\).问将数列清零至少需要 ...

  3. 1154 能量项链 2006年NOIP全国联赛提高组 codevs

    1154 能量项链  2006年NOIP全国联赛提高组 codevs 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头 ...

  4. [NOIP2013 提高组] 华容道 P1979 洛谷

    [NOIP2013 提高组] 华容道 P1979 洛谷 强烈推荐,更好的阅读体验 经典题目:spfa+bfs+转化 题目大意: 给出一个01网格图,和点坐标x,y空格坐标a,b,目标位置tx,ty要求 ...

  5. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  6. Codevs 3287 货车运输 == 洛谷P1967

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编 ...

  7. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

  8. [NOIP2012提高组] CODEVS 1200 同余方程(扩展欧几里德算法)

    数论题..所有数论对我来说都很恶心..不想再说什么了.. ------------------------------------------------ #include<iostream&g ...

  9. NOIP2010提高组] CODEVS 1069 关押罪犯(并查集)

    这道这么简单的题目还写了这么久.. 将每个会发生冲突的两人的怒气进行排序,然后从怒气大到小,将两个人放到不同监狱中.假如两人都已经被放置且在同一监狱,这就是答案. ------------------ ...

随机推荐

  1. poj1552---枚举

    #include <stdio.h> #include <stdlib.h> int main() { ],th=,i,j; while(scanf("%d" ...

  2. New Relic——手机应用app开发达人的福利立即就到啦!

    HiWork集成的第三方服务(机器人)将有新的添加啦,添加了BitBucket和New Relic.分别做下介绍啦! 1.BitBucket BitBucket 是一家源码托管站点.採用Mercuri ...

  3. BootStrap 模态框禁用空白处点击关闭问题

    模态框为信息编辑窗口,涉及好多内容,填了半天,若一不小心点了空白处,那就前功尽弃了..... 所以我们很有必要禁用鼠标点击空白处模态框关闭的功能. $('#myModal').modal({backd ...

  4. Java 中的resultset详解

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

  5. win7+cygwin+hadoop+eclipse

    1.Cygwin : Net    下的:openssh,openssl Base  下的:sed (若需要Eclipse,必须sed)默认即可 Devel 下的:subversion(建议安装) 2 ...

  6. objective-C学习笔记(一)OBJC简介

    如何掌握一门高级编程语言:(这里特指Objective-C) 底层思维:   向下,如何从机器底层的角度来思考程序运行的过程. 关注语言构造.编译转换.内存模型.运行时机制 抽象思维:   向上,当软 ...

  7. oracle中 some、any、all 三者的区别及个人总结,归纳!

    any :如果是大于号时( a > b ),那么a中所有大于b中最小的那个数的值,就会被输出出来. 如果是小于号时( a < b ),那么a中所有小于b中最大的那个数的值,就会被输出出来. ...

  8. C++_知识点_结构体/枚举/联合

    //C++中结构体的不同之处 #include <iostream> #include <string> using namespace std; int main(void) ...

  9. github版本库使用详细图文教程(命令行及图形界面版)

    投稿:mdxy-dxy 字体:[增加 减小] 类型:转载 时间:2015-08-06我要评论 今天我们就来学习github的使用,我们将用它来管理我们的代码,你会发现它的好处的,当然是要在本系列教程全 ...

  10. Struts学习之文件上传

    * 单文件上传:        * 在动作类action中声明相关属性:            * 在动作类action中,要声明与页面中表单name属性同名的属性,同名的属性的类型是File类型:  ...