洛谷P1966 [NOIP2013提高组Day1T2]火柴排队

P1966 火柴排队

题目描述

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2

其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。

每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

输入输出格式

输入格式:

输入文件为 match.in。

共三行,第一行包含一个整数 n,表示每盒中火柴的数目。

第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。

第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出格式:

输出文件为 match.out。

输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果。

输入输出样例

输入样例#1:
4
2 3 1 4
3 2 1 4
输出样例#1:
1
输入样例#2:
4
1 3 4 2
1 7 2 4
输出样例#2:
2

说明

【输入输出样例说明1】

最小距离是 0,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。

【输入输出样例说明2】

最小距离是 10,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。

【数据范围】

对于 10%的数据, 1 ≤ n ≤ 10;

对于 30%的数据,1 ≤ n ≤ 100;

对于 60%的数据,1 ≤ n ≤ 1,000;

对于 100%的数据,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ maxlongint

【题解】

十分显然

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #define min(a, b) ((a) < (b) ? (a) : (b))
  7 
  8 inline void read(int &x)
  9 {
 10     x = 0;char ch = getchar(), c = ch;
 11     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 12     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 13     if(c == '-') x = -x;
 14 }
 15 
 16 inline void swap(int &a, int &b)
 17 {
 18     int tmp = a;a = b;b = tmp;
 19 }
 20 
 21 const int MAXN = 10000 + 10;
 22 const int MAXM = 50000 + 10;
 23 const int INF = 0x3f3f3f3f;
 24 
 25 int n,m,u[MAXM],v[MAXM],w[MAXM],cnt[MAXM],q,s,t,fa[MAXN],b[MAXM];
 26 
 27 bool cmp(int a, int b)
 28 {
 29     return w[a] > w[b];
 30 }
 31 
 32 struct Edge
 33 {
 34     int u,v,w,next;
 35     Edge(int _u, int _v, int _w, int _next){u = _u, v = _v, w = _w, next = _next;}
 36     Edge(){}
 37 }edge[MAXN << 1];
 38 int head[MAXN], cntt;
 39 inline void insert(int a, int b, int c)
 40 {
 41     edge[++cntt] = Edge(a,b,c,head[a]);
 42     head[a] = cntt;
 43 }
 44 
 45 int deep[MAXN], p[20][MAXN], mi[20][MAXN];
 46 
 47 void dfs(int u)
 48 {
 49     b[u] = 1;
 50     for(register int pos = head[u];pos;pos = edge[pos].next)
 51     {
 52         int v = edge[pos].v;
 53         if(b[v])continue;
 54         deep[v] = deep[u] + 1;
 55         p[0][v] = u;
 56         mi[0][v] = edge[pos].w;
 57         dfs(v);
 58     }
 59 }
 60 
 61 void yuchuli()
 62 {
 63     int M = 0;
 64     while((1 << M) <= n) ++ M;
 65     -- M;
 66     for(register int i = 1;i <= M;++ i)
 67         for(register int j = 1;j <= n;++ j)
 68             p[i][j] = p[i - 1][p[i - 1][j]];
 69     for(register int i = 1;i <= M;++ i)
 70         for(register int j = 1;j <= n;++ j)
 71             mi[i][j] = min(mi[i - 1][p[i - 1][j]], mi[i - 1][j]);
 72 }
 73 
 74 int LCA(int va, int vb)
 75 {
 76     if(deep[va] < deep[vb]) swap(va, vb);
 77     int M = 0;
 78     while((1 << M) <= n)++ M;
 79     -- M;
 80     for(register int i = M;i >= 0;-- i)
 81         if(deep[vb] + (1 << i) <= deep[va])
 82             va = p[i][va];
 83     if(va == vb)return va;
 84     M = 0;
 85     while((1 << M) <= deep[va]) ++ M;
 86     -- M;
 87     for(register int i = M;i >= 0;-- i)
 88         if(p[i][va] != p[i][vb])
 89         {
 90             va = p[i][va];
 91             vb = p[i][vb];
 92         }
 93     return p[0][va];
 94 }
 95 
 96 int find(int x)
 97 {
 98     return x == fa[x] ? x : fa[x] = find(fa[x]);
 99 }
100 
101 int main()
102 {
103     read(n), read(m);
104     for(register int i = 1;i <= m;++i)
105         read(u[i]), read(v[i]), read(w[i]), cnt[i] = i;
106     for(register int i = 1;i <= n;++ i)
107         fa[i] = i;
108     std::sort(cnt + 1, cnt + 1 + m, cmp);
109     for(register int i = 1;i <= m;++i)
110     {
111         int f1 = find(u[cnt[i]]), f2 = find(v[cnt[i]]);
112         if(f1 != f2)
113         {
114             fa[f1] = f2;
115             insert(u[cnt[i]], v[cnt[i]], w[cnt[i]]);
116             insert(v[cnt[i]], u[cnt[i]], w[cnt[i]]);
117         }
118     }
119     for(register int i = 1;i <= n;++ i)
120     {
121         if(!b[i])
122         {
123             deep[i] = 1;
124             dfs(i);
125         }
126     }
127     yuchuli();
128     read(q);
129     int s,t;
130     int M = 0;
131     while((1 << M) <= n) ++ M;
132     -- M;
133     for(register int i = 1;i <= q;++ i)
134     {
135         read(s), read(t);
136         int f1 = find(s), f2 = find(t);
137         if(f1 != f2)
138         {
139             printf("-1
");
140             continue;
141         }
142         int lca = LCA(s, t);
143         int mi1 = INF, mi2 = INF;
144         for(register int j = M;j >= 0;-- j)
145             if(p[j][s] && deep[p[j][s]] >= deep[lca])
146             {
147                 mi1 = min(mi1, mi[j][s]);
148                 s = p[j][s];
149             }    
150         for(register int j = M;j >= 0;-- j)
151             if(p[j][t] && deep[p[j][t]] >= deep[lca])
152             {
153                 mi2 = min(mi2, mi[j][t]);
154                 t = p[j][t];
155             }
156         printf("%d
", min(mi1, mi2));
157     }
158     return 0;
159 }
NOIP2013Day1T2
原文地址:https://www.cnblogs.com/huibixiaoxing/p/7544750.html