记录编号 |
318305 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOIP 2013]货车运输 |
最终得分 |
100 |
用户昵称 |
小e |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.091 s |
提交时间 |
2016-10-09 08:09:00 |
内存使用 |
2.67 MiB |
显示代码纯文本
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
int n, m, q;
const int maxedge = 50100, maxnumber = 10100;
struct Edge
{
int from, to, w, next;
}e[maxedge << 1], edges[maxnumber << 1];
int head[maxnumber], tot;
int root[maxnumber];
int weight[maxnumber];
int depth[maxnumber], size[maxnumber], fa[maxnumber], son[maxnumber];
int dfn[maxnumber], id[maxnumber], top[maxnumber], dfsclock;
int minn[maxnumber << 2];
inline void Read(int& a)
{
a = 0;
char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){
a = a * 10 + ch - '0';
ch = getchar();
}
}
inline void Write(int a)
{
int cnt = 0;
char ch[50] = {'\0'};
while(1){
ch[++cnt] = a % 10 + '0';
a /= 10;
if(!a) break;
}
while(cnt) putchar(ch[cnt--]);
puts("");
}
inline void AddEdge(const int& from, const int& to, const int& w)
{
edges[++tot].to = to;
edges[tot].w = w;
edges[tot].next = head[from];
head[from] = tot;
}
int FindRoot(const int& a)
{
if(root[a] != a) root[a] = FindRoot(root[a]);
return root[a];
}
inline void Union(const int& a, const int& b)
{
int ra = FindRoot(a), rb = FindRoot(b);
root[ra] = rb;
}
inline bool cmp(const Edge& a, const Edge& b)
{
return a.w > b.w;
}
inline void Kruskal()
{
sort(e+1, e+1+m*2, cmp);
int cnt = 0;
for(int i = 1; i <= m * 2; i++){
int from = e[i].from, to = e[i].to, w = e[i].w;
if(FindRoot(from) != FindRoot(to)){
Union(from, to);
cnt++;
AddEdge(from, to, w);
AddEdge(to, from, w);
}
if(cnt == n - 1) return;
}
}
void Segment_Tree_Build(const int& l, const int& r, const int& rt)
{
if(l == r){
minn[rt] = weight[id[l]];
// printf("minn[%d]:%d ", rt, minn[rt]);
return;
}
const int mid = (l + r) >> 1, lch = rt << 1, rch = lch | 1;
Segment_Tree_Build(l, mid, lch);
Segment_Tree_Build(mid+1, r, rch);
minn[rt] = min(minn[lch], minn[rch]);
}
int Segment_Tree_Min(const int& l, const int& r, const int& rt, const int& s, const int& t)
{
if(s <= l && t >= r) return minn[rt];
const int mid = (l + r) >> 1, lch = rt << 1, rch = lch | 1;
if(t <= mid) return Segment_Tree_Min(l, mid, lch, s, t);
else if(s >= mid + 1) return Segment_Tree_Min(mid+1, r, rch, s, t);
return min(Segment_Tree_Min(l, mid, lch, s, mid), Segment_Tree_Min(mid+1, r, rch, mid+1, t));
}
void DFS1(const int& a)
{
size[a] = 1;
for(int i = head[a]; i; i = edges[i].next){
int to = edges[i].to, w = edges[i].w;
if(to == fa[a]) continue;
depth[to]= depth[a] + 1;
fa[to] = a;
weight[to] = w;
DFS1(to);
if(size[to] > size[son[a]]) son[a] = to;
size[a] += size[to];
}
}
void DFS2(const int& a, const int& tp)
{
top[a] = tp;
dfn[a] = ++dfsclock;
id[dfsclock] = a;
if(son[a]) DFS2(son[a], tp);
for(int i = head[a]; i; i = edges[i].next){
int to = edges[i].to;
if(to == fa[a] || to == son[a]) continue;
DFS2(to, to);
}
}
inline int Query_Min(int s, int t)
{
int f1 = top[s], f2 = top[t], ret = 0x7fffffff;
while(f1 != f2){
if(depth[f1] < depth[f2]){
swap(f1, f2);
swap(s, t);
}
ret = min(ret, Segment_Tree_Min(1, n, 1, dfn[f1], dfn[s]));
s = fa[f1];
f1 = top[s];
}
if(s == t) return ret;
if(depth[s] < depth[t]) swap(s, t);
ret = min(ret, Segment_Tree_Min(1, n, 1, dfn[son[t]], dfn[s]));
return ret;
}
#define SUBMIT
int main(int argc, char const *argv[])
{
#ifdef SUBMIT
freopen("truck.in", "r", stdin); freopen("truck.out", "w", stdout);
#endif
memset(weight, 0x3f, sizeof(weight));
Read(n); Read(m);
int from, to, w, s, t, cnt = 0;
for(int i = 1; i <= n; i++) root[i] = i;
for(int i = 1; i <= m; i++){
Read(from); Read(to); Read(w);
e[++cnt].from = from; e[cnt].to = to; e[cnt].w = w;
e[++cnt].from = to; e[cnt].to = from; e[cnt].w = w;
}
Kruskal();
depth[1] = 1;
DFS1(1);
DFS2(1, 1);
// for(int i = 1; i <= n; i++) printf("weight[%d]:%d n", i, weight[i]); printf("\n");
Segment_Tree_Build(1, n, 1);
Read(q);
for(int i = 1; i <= q; i++){
Read(s); Read(t);
if(!dfn[s] || !dfn[t]) puts("-1");
else Write(Query_Min(s, t));
}
#ifndef SUBMIT
printf("\n----------\n");
getchar(); getchar();
#else
fclose(stdin); fclose(stdout);
#endif
return 0;
}