小白月赛54 F.Traveling(图论&构造)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小白月赛54 F.Traveling(图论&构造)相关的知识,希望对你有一定的参考价值。
小白月赛54 F.Traveling(图论&构造)
显然 d 1 = d n = min d i d_1=d_n=\\min d_i d1=dn=mindi
考虑 d i = d 1 ( m o d 2 ) d_i=d_1\\pmod 2 di=d1(mod2) 的 i i i,可以构造 ( 1 , i , d i − d 1 2 ) (1,i,\\dfracd_i-d_12) (1,i,2di−d1)
接下来只需考虑 d i ≠ d 1 ( m o d 2 ) d_i\\ne d_1\\pmod2 di=d1(mod2) 的集合 S S S。
我们可以选择最小的 d x d_x dx 然后连 ( 1 , x , d x − d 1 ) , ( x , n , d 1 ) (1,x,d_x-d_1),(x,n,d_1) (1,x,dx−d1),(x,n,d1)
然后集合 S S S中的其他点连 ( x , i , d i − d x 2 ) (x,i,\\dfracd_i-d_x2) (x,i,2di−dx)。
注意特判 m < n − 1 , m > n ( n − 1 ) 2 m<n-1,m>\\dfracn(n-1)2 m<n−1,m>2n(n−1)和构造的边数小于 m m m 和大于 m m m的情况。
不足 m m m 可以构造无效边 ( u , v , 1 e 9 ) (u,v,1e9) (u,v,1e9)
超过 m m m无解。
#include <bits/stdc++.h>
using namespace std;
const int N = 3E5 + 100, inf = 1E9;
int n, m;
int arr[N];
set<int> vis[N];
int main()
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
int Min = numeric_limits<int>::max();
for (int i = 1; i <= n; i++)
cin >> arr[i];
Min = min(Min, arr[i]);
if (m > 1LL * n * (n - 1) / 2 || arr[1] > Min || arr[n] > Min)
cout << "No" << "\\n";
return 0;
vector<array<int, 3> > e;
vector<array<int, 2> > v;
e.push_back(1, n, Min);
vis[1].insert(n);
for (int i = 2; i < n; i++)
int d = arr[i] - arr[1];
if (d & 1)
if (arr[1] == 0)
cout << "No" << "\\n";
return 0;
v.push_back(arr[i], i);
else
e.push_back(1, i, d / 2);
vis[1].insert(i);
sort(v.begin(), v.end());
if (!v.empty())
auto [d1, x] = v.front();
auto d0 = arr[1];
e.push_back(1, x, d1-d0);
vis[1].insert(x);
e.push_back(x, n, d0);
vis[x].insert(n);
for (int i = 1; i < v.size(); i++)
auto [d2, y] = v[i];
if (x < y)
e.push_back(x, y, (d2 - d1) / 2);
vis[x].insert(y);
else
e.push_back(y, x, (d2 - d1) / 2);
vis[y].insert(x);
if (m < e.size())
cout << "No" << "\\n";
return 0;
for (int i = 1; i <= n && e.size() < m; i++)
for (int j = i + 1; j <= n && e.size() < m; j++)
if (vis[i].find(j) == vis[i].end())
e.push_back(i, j, inf);
vis[i].insert(j);
cout << "Yes" << "\\n";
for (auto [u, v, w] : e)
cout << u << " " << v << " " << w << "\\n";
return 0;
以上是关于小白月赛54 F.Traveling(图论&构造)的主要内容,如果未能解决你的问题,请参考以下文章