![](https://dpic.tiankong.com/91/k9/QJ8305395156.jpg?x-oss-process=style/240h)
A.Asia区域赛:
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
2018年11月24日至25日,由我校承办的第43届ACM国际大学生程序设计竞赛亚洲区域赛(焦作站)在学校体育馆举行。来自清华大学、北京大学、香港中文大学、蒙古国立大学等国内外186所高校以及3所中学和1家企业的298支参赛队伍共计894名计算机算法设计精英及226名教练参加比赛。
24日下午,大赛在雄壮的国歌声中拉开帷幕。大赛亚洲区域主席黄金雄、河南省计算机学会理事长周清雷、校党委副书记安士伟、校教务处副处长原东方、计算机科学与技术学院院长贾宗璞、计蒜客首席布道师钦恩强出席开幕式。全体裁判员、参赛师生、学生志愿者等1400余人参加开幕式。
大赛亚洲区主席黄金雄教授对于焦作站的准备工作给予高度的赞扬,周清雷对此次大赛在我校的举办表示热烈祝贺。安士伟在致辞中简要介绍了学校的办学情况及计算机学院的发展现状,他充分肯定了ACM国际大学生程序设计竞赛对于提高IT创新人才培养水平、促进计算机教育事业和人工智能发展的重要意义。他表示,国际大学生程序设计竞赛亚洲区域赛在我校举办,既是对我校的高度信任,也是我校学习提高的一次难得的机会。他希望参加本届大赛的老师和同学们能够深入交流、增进友谊、互相切磋、共同进步。开幕式结束后,随即开展了历时2个小时的热身赛,参赛选手们在热身赛中熟悉了比赛环境和流程。
25日上午9时,比赛正式开始,经过5个小时的激烈角逐,大赛落下帷幕。本次大赛29支队伍获得金奖、58支队伍获得银奖、87支队伍获得铜奖、11支队伍获得最快解题奖、1支队伍获得最佳女队奖、1支队伍获得顽强拼搏奖。清华大学的“随串鸡”代表队获得第一名,清华大学、中山大学和西安交通大学分别赢得冠军、亚军和季军。副校长赵同谦为获得冠军、亚军和季军的队伍颁奖。
此次大赛由我校承办是该项国际赛事首次进入河南高校,为加强我校对外交流与合作、展示我校办学水平提供了宝贵的机会和平台,对进一步探讨教育教学改革的经验和做法、推进我校计算机类学科建设、培育拔尖创新人才具有重要意义。
输入:
本题没有输入要求.
输出:
请输出文中表述的发放奖牌个数,并单独占一行.
提示:
本题只需按照题目描述,输出一个整数即可(无需纠结比赛规则问题).
理解:
看完题目描述有点犹豫,刚刚开始被清华得奖那俩句搞懵了,难怪高考语文不及格。
#include<stdio.h>
int main(void)
{
printf("187");
return 0;
}
![](https://dpic.tiankong.com/wi/ep/QJ8445880668.jpg?x-oss-process=style/240h)
B.Asia区域制
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
二进制数据是用 0 和 1 两个数码来表示的数.它的基数为 2 ,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹发现.
十六进制(简写为hex或下标 16 )在数学中是一种逢 16 进 1 的进位制.一般用数字 0 到 9 和字母 A 到 F(或 a ~ f )表示,
其中: a ~ f 表示 10 ~ 15 ,这些称作十六进制数字.
请将给定的二进制数转为十六进制数,英文字母使用小写形式.
输入:
第一行一个正整数 T, 代表有 T 组测试数据. (1≤T≤10).
接下来 T 行,每行输入一串只包含 0 和 1 的字符串(无前导 0),
字符串长度:1≤length≤106.
输出:
对于每组测试样例,输出转化后的十六进制数并单独占一行.
理解:
按照每四位二进制转变成一位十六进制,从后往前模拟,注意前导零,注意输出的字母是小写
样例:
input
2
1
10
output
1
2
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char a[1000002];//存二进制
int b[1000002]={0};//存十六进制
int main()
{
int N,n,k,t,i,j,m;
scanf("%d",&N);
while(N--)
{
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
scanf("%s",a);//读取二进制
n=strlen(a);
k=0;
t=1;
m=0;
for(i=n-1;i>=0;i--)
{
b[k]+=(a[i]-'0')*t;
t*=2;
m++;
if(m%4==0)//每到四位增加十六进制一位
{
k++;
t=1;
}
}
for(i=0;i<n;i++)//十六进制中大于9的用字母的ASCLL表示
{
if(b[i]>=10)
{
b[i]=97+b[i]-10;
}
}
for(i=k;i>=0;i--)//输出
{
if(b[i]!=0)
{
for(j=i;j>=0;j--)
{
if(b[j]>='a' && b[j]<='z' )
printf("%c",b[j]);
else printf("%d",b[j]);
}
break;
}
}
printf("\n");
}
}
![](https://dpic2.tiankong.com/x1/ac/QJ8532494814.jpg?x-oss-process=style/240h)
C. Asia区域宫
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
远古洪荒时期,女王Alice和战神Bob因爱相恋,一段催人泪下的爱情故事流传民间.
相传,女王Alice的美貌惊艳六界,作为对颜值颇有要求的上古灵兽Qaq芳心异动,可是女王早已许配给战神Bob,怎么会移情于己呢,而且单挑自己也不是战神Bob的对手。于是,灵兽Qaq便设计将战神Bob引入洪荒之地,种下十里桃花困住战神Bob。
女王Alice得知后,冒着渡劫的天雷赶去营救……实在bian不下去了.
简言之,一个 n×n 的迷宫,Alice站在 (1,1) 位置,Bob被困在 (n,n) 位置,迷宫中会有障碍物,规定障碍物在迷宫中不能同行且不能同列。
Alice只能在迷宫中移动且不能跨越障碍物,每次只能移动一个格子且只有上下左右四个方向。
Alice能顺利解救Bob么?
若成功解救输出 Yes,并输出最少所用步数.
否则输出 No.
如图所示,A 代表Alice,B 代表Bob,# 代表障碍物,箭头代表移动的四个方向:
输入:
第一行一个整数 T,代表 T 组测试数据.
对于每一组数据,
第一行两个整数 n 和 m,分别表示 n×n 迷宫大小和 m 个障碍物,
接下来 m 行,每一行两个整数 x 和 y,表示障碍物坐标 (x,y)。
数据保证障碍物不同行且不同列,且不在位置 (1,1),(n,n)。
(1≤T≤2000,1≤m,n≤10000,1≤x,y≤n)
输出:
对于每组测试样例,输出占一行。
若成功解救输出 Yes,并输出最少所用步数.否则输出 No 。
样例:
input
2
2 1
1 2
2 2
1 2
2 1
output
Yes 2
No
理解:
学习别人的:自己写注释理解
障碍物在迷宫中不能同行且不能同列这句话,
也就是说走不通的情况只有当障碍物在同一条左下到右上的对角线的情况
所以走不通的情况就转变成了下图红线标注的情况,
可以发现这些位置均为n×n方针的对角线, 并要有n个连续的才可以,
所以只需要判断在一条线上的障碍物的个数就可以了
![](https://i-blog.csdnimg.cn/blog_migrate/5fbb0252ae8ef05fbfc9cddbbf1db254.png)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
const int maxn=1e6+10;
const int maxm=1e4+10;
const int inf=(1<<30);
const ll INF=(1LL*1<<60);
using namespace std;
int vis[maxn];
void init()//记录对角线全部都是障碍的数量
{
for(int i=2;i<=maxm;i++)
vis[i+1]=i;
}
int arr[maxm];
int sum[maxn];
int main()
{
int t;
init();
cin>>t;
while(t--)
{
ms(sum,0);
int n,m;
cin>>n>>m;
int x,y;
for(int i=0;i<m;i++)
{
cin>>x>>y;
arr[i]=x+y;//把同一条对角线的障碍记录在一起
sum[x+y]++;//记录这条对角线上障碍物的个数
}
sort(arr,arr+m);
m=unique(arr,arr+m)-arr;
/*一般使用前需要对容器进行排序,这样才能实现对整个数组去重。
如果要对结构体进行这一操作,需要重载运算符"==",
unique
的作用是“去掉”容器中相邻元素的重复元素,
它会把重复的元素添加到容器末尾,
而返回值是去重之后的尾地址(是地址!!)
*/
int flag=0;
for(int i=0;i<m;i++)
{
if(sum[arr[i]] == vis[arr[i]])//判断是否全为障碍
{
flag=1;
break;
}
}
if(flag)
cout<<"No"<<endl;
else
cout<<"Yes "<<2*n-2<<endl;
}
return 0;
}
![](https://dpic.tiankong.com/73/ig/QJ7116663052.jpg?x-oss-process=style/240h)
D. Asia区域阵
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
一个 n×m 的矩阵,由 A−Z 字符将其填充. 现在我们定义一个异矩阵:
同一行字符都不相同的矩阵。
同一列字符都不相同的矩阵。
求解异矩阵的最大面积。
输入:
第一行一个正整数 T, 代表有 T 组测试数据。(1≤T≤10)
每组数据第一行输入正整数 n,m,表示 n 行 m 列的一个矩阵。(1≤n,m≤100)
输出:
输出单独占一行,表示最大异矩阵面积.
样例
input
1
2 3
HPU
UHP
output
6
求解。。。。。无奈。。。。
![](https://dpic2.tiankong.com/1l/2w/QJ8842538574.jpg?x-oss-process=style/240h)
E. Mo的游戏
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
Mo翻书看到一种新的连连看游戏:对于一个字符串来说,只有当两个字符相同时候才可以进行相连,
得分为字符串的长度减去两个相连字符的距离(如果整个字符串中某一种字符个数为1,那么不能相连故得分为0)。
Mo现在在玩这个游戏,但是Mo不知道该选择哪一种字符进行相连,所以请你列出每种字符相连可以获得的最大分数,以此来让Mo进行参考。
输入
一个字符串s (0<strlen(s)<106, s中只包含大小写字符)。
输出
针对s中出现过的字符,每行输出一个整数表示用当前字符进行相连可以获得的最大分数, 按照a−z,A−Z的顺序。具体格式参见样例。
样例:
input:
Aabcaabcb
output:
a:8
b:7
c:5
A:0
理解:
也是模拟,注意一下每个字符第一次出现的情况就行了。
保存这个字符上一次出现的位置,然后根据现在这个位置和保存的上个位置的差值来进行求解。如果之前没有出现过这个字符,那么就跳过,不用计算。
自己写的时候是开了二维数组,初始化为 INT_MAX,然后getchar()分别记录每个字母出现的位置,最后在找出每个字母距离最小值,得出答案。下面是学习大佬的代码。
#include<bits/stdc++.h>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
const int maxn=1e6+10;
const int maxm=1e3+10;
const int inf=(1<<30);
const ll INF=(1LL*1<<60);
using namespace std;
vector<int>v[100];
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
string s;
cin>>s;
int l=s.length();
map<char,int>mp;
for(int i=0;i<l;i++)
{
mp[s[i]]++;
v[s[i]-'A'].push_back(i);
}
for(int i='a';i<='z';i++)
{
if(!mp[i])
continue;
cout<<(char)i<<":";
if(mp[i]==1)
{
cout<<0<<endl;
continue;
}
int minn=inf;
for(int j=0;j<v[i-'A'].size()-1;j++)
{
for(int k=j+1;k<v[i-'A'].size();k++)
{
minn=min(v[i-'A'][k]-v[i-'A'][j],minn);
if(minn==1)
break;
}
}
cout<<l-minn<<endl;
}
for(int i='A';i<='Z';i++)
{
if(!mp[i])
continue;
cout<<(char)i<<":";
if(mp[i]==1)
{
cout<<0<<endl;
continue;
}
int minn=inf;
for(int j=0;j<v[i-'A'].size()-1;j++)
{
for(int k=j+1;k<v[i-'A'].size();k++)
{
minn=min(v[i-'A'][k]-v[i-'A'][j],minn);
if(minn==1)
break;
}
}
cout<<l-minn<<endl;
}
return 0;
}
![](https://dpic3.tiankong.com/m3/th/QJ8458132747.jpg?x-oss-process=style/240h)
F. Mo的极限
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
Mo今天遇到了一个极限问题,他不会,故请教你。
给两个多项式 f(x) 和 F(x) , 求
保证每个多项式中每一项都表示为:kxy,y 为整数 0≤y≤1000,k 为整数且 |k|≤1000 , F(x)≠0 。
输入
第一行表示 f(x)。
第二行表示 F(x)。
输出
limx→+∞f(x)F(x)
的值。
如果是无穷大输出 oo。
如果是无穷小输出 0。
其余的输出 最简分数。
理解:
思路是:找出 n ! (n的阶乘),然后除以不符合条件的数(不互质的数)。
然后我们对 m 的因子进行处理,可以知道的是,如果m的质因子 a ,那么 a * x(x>0) 必然与 m 不互质,
而且在 [ 1 , n ] 的范围内 a 的倍数相乘结果为
f(a)=an/a∗(n/a)! ,因为区间内 a 的倍数只有 n / a 个,
然后就是容斥定理。
但是在除以 f(a) 时,可能会出现除不尽的情况,因此需要用逆元来处理一下。
样例
一。input:
2x^2-3x^1+4x^0
10x^0+3x^2
output:
2/3
二。input:
1x^1
1x^1
output:
1
学习中。。。
![](https://dpic3.tiankong.com/m3/th/QJ8458132747.jpg?x-oss-process=style/240h)
G. Mo的数学
单测试点时限: 1.0 秒
内存限制: 512 MB
题目描述:
Mo偶然间得到一个数学问题,听说你很擅长数学,于是前来虚心请教!
求区间 [1,n] 中 与 m互质的数的乘积。
输入
多组输入(不超过100组)
每行两个整数 n和 m. ( 0<n≤106, 0<m≤109)
输出
每行输出一个答案.(由于答案很大,故请输出对 109+7
取模后的结果)
理解:
容斥定理+逆元。
这个如果直接用循环就会超时。
我们先预处理 1 ~ n 的阶乘,可以省下不少时间。
思路是:找出 n ! (n的阶乘),然后除以不符合条件的数(不互质的数)。
然后我们对 m 的因子进行处理,可以知道的是,如果m的质因子 a ,那么 a * x(x>0) 必然与 m 不互质,而且在 [ 1 , n ] 的范围内 a 的倍数相乘结果为
f(a)=an/a∗(n/a)! ,因为区间内 a 的倍数只有 n / a 个,然后就是容斥定理。但是在以
f(a) 时,可能会出现除不尽的情况,因此需要用逆元来处理一下。
样例
input
3 2
output
3
#include<bits/stdc++.h>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
const int maxn=1e6+10;
const int maxm=1e3+10;
const int inf=(1<<30);
const ll INF=(1LL*1<<60);
const int mod=1e9+7;
using namespace std;
int arr[maxn];
int p;
int pr[maxn];
int mp[maxn];
void getp(int n)
{
p=0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
arr[p++]=i;
while(n%i==0)
n/=i;
}
}
if(n>1)
arr[p++]=n;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
int n,m;
while(cin>>n>>m)
{
ms(mp,0);
int cnt=0;
getp(m);
for(int i=0;i<p;i++)
{
for(int j=1;j*arr[i]<=n;j++)
{
mp[arr[i]*j]++;
}
}
ll ans=1;
for(int i=1;i<=n;i++)
{
if(!mp[i])
ans=1LL*(ans%mod*1LL*i%mod)%mod;
}
cout<<ans<<endl;
}
return 0;
}
![](https://dpic2.tiankong.com/ed/fz/QJ8391135450.jpg?x-oss-process=style/240h)
H. Mo的面积
题目描述:
Mo的老师给了他两个矩形,让他求两个矩形的面积并。Mo很忙没时间解决这种小case,请你帮他解决。
输入
输入两行,每行四个整数 x,y,x1,y1 。(x,y)是矩形左下角,(x1,y1) 是矩形的右上角. (0≤x,y,x1,y1≤1000)。
输出
输出一个整数表示二个矩形的面积并。
理解:
菜鸟理解-----直接把包括的面赋值一,最后搜索1的个数即为面积。
样例
input
0 1 2 3
1 0 3 2
output
7
C代码
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int a[1001][1001]={0};
int main()
{
int i,j,k=8;
int b[10];
while(k--)
{
scanf("%d",&b[7-k]);
}
for(i=b[0];i<b[2];i++)
{
for(j=b[1];j<b[3];j++)
{
a[i][j]=1;
}
}
for(i=b[4];i<b[6];i++)
{
for(j=b[5];j<b[7];j++)
{
a[i][j]=1;
}
}
int minx= b[0]>b[4] ? b[4] : b[0];//缩时间
int maxx= b[2]>b[6] ? b[2] : b[6];
int miny= b[1]>b[5] ? b[5] : b[1];
int maxy= b[3]>b[7] ? b[3] : b[7];
int sum=0;
for(i=minx;i<maxx;i++)
{
for(j=miny;j<maxy;j++)
{
if(a[i][j]==1)sum++;
}
}
printf("%d\n",sum);
return 0;
}
![](https://dpic.tiankong.com/5p/tf/QJ6564241016.jpg?x-oss-process=style/240h)
I. 安全距离
单测试点时限: 2.0 秒
内存限制: 512 MB
题目描述:
在一个三维空间中给定一个三角形薄片和一个球形安全区,现在需要求出这个三角形薄片到安全区的最短距离。若三角形薄片上的某点在安全区内,则最短距离为零。
输入
第一行一个整数 n,( n≤103)。之后的 n 行,每行 13 个整数
x1 y1 z1
x2 y2z2
x3y3z3
xo yo zo
r。
(x1,y1,z1),(x2,y2,z2),(x3,y3,z3) 表示三角形薄片的三个顶点(xoyozo),r 表示球的球心和半径。
数据保证所有的数均不超过 103。
输出
n
行,每行一个实数为所求答案,请保留6位小数(四舍五入)。
理解:
二分适用于单调性的区间,由于这个题目球面是个弧线,
并不是直线,因此需要用三分来求解。然后我们就用三分的思想来求解。
样例:
input
3
0 0 0 0 0 1 0 1 0 2 0 0 1
1 0 5 0 0 1 0 1 0 2 0 0 1
0 0 0 0 0 1 0 1 0 0 0 0 1
output
1.000000
1.121320
0.000000
不会,,,,,,
![](https://dpic.tiankong.com/we/6b/QJ6526013276.jpg?x-oss-process=style/240h)
J. 简单递归
题目描述:
这是一段 C/C++ 代码,用于计算递推数列 an 的。
const int MOD = (int)1e9 + 7;
int a(int n) {
if(n < 3) return 1;
return ((a(n - 1) << 1) % MOD + (a(n - 2) >> 1)) % MOD;
}
现在请根据这段代码输出第 n 项数列的值 an 。
输入
第一行一个整数 T。之后的 T 行,每行 1 个整数,表示 n 。0<T≤105, 0<n≤106 。
输出
每一行请输出一个 an的值。
样例:
input
3
1
2
3
output
1
1
2
#include<cstdio>
#include<iostream>
using namespace std;
int b[1000001]={1,1};
int MOD = (int)1e9 + 7;
int a(int n)
{
return ((b[n-1] << 1) % MOD + (b[n-2] >> 1)) % MOD;
}
int main()
{
int i,j,k;
for(i=2;i<1000001;i++) b[i]=a(i);//存储
scanf("%d",&k);
while(k--)
{
scanf("%d",&i);
printf("%d\n",b[i-1]);
}
return 0;
}
K. 高度期望
题目描述:
这里是
22世纪,有一款神奇的机器,可以使任意一棵树长到任意高度但不超过 1000 cm,但是该机器却只能使用一次。
为了提升整片树林的平均树高,使得平均树高大于某个值,请设计提升方案。
我们的 Boss 对方案本身不感兴趣,你只需要提供提升后需要的机器数量。
输入:
第一行 2 个整数 n, m, 表示有 n 颗树和期望的最小平均树高 m cm。之后的一行 n 个数a
1 a2⋯an,表示 n 颗树的高度。0<n≤105, 0<m≤103,0<a1 a2⋯an≤103。
输出:
输出提升平均树高所需要的最少机器数量。
样例
input:
5 1000
1000 1000 1000 500 1000
output:
1
学长帮忙改过 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e6+7;
int a[maxn];
int main()
{
int n,m,i,sum=0,cha;//a为还差多少达到平均值;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];//累加然后作比较,不取平均值,避免平均值会出现小数
}
if(sum>=(n*m))//如果总值超过平均值乘以个数
printf("0");//不需要用
else
{
int ans=0;
sort(a,a+n);//排序
cha=n*m-sum;//差多少
for(i=0;i<n;i++)
{
if(cha>0)//差>0
ans++;//加一次
if(cha<=0)//差<=0的话
break;// 跳出循环
cha=cha-(1000-a[i]);//用一次后还差多少
}
printf("%d",ans);
}
}
![](https://dpic3.tiankong.com/cu/ex/QJ6426683559.jpg?x-oss-process=style/240h)
L. 最优规划
题目描述:
有很多城市之间已经建立了路径,但是有些城市之间没有路径联通。为了联通所有的城市,现在需要添加一些路径,为了节约,需要满足添加总路径是最短的。
输入:
第一行 3 个整数 n, m, s, 分别表示城市的数量、已经存在的路的数量、可修的路的数量。
之后的 m行,每行 3个整数 x, y, d,表示点 x 到点 y有一条长度为 d的已经存在的路径。
之后的 s 行,每行 3 个整数 x, y, d,表示点 x 到点 y 有一条长度为 d 的可修的路径。0<n,m,s,d≤105 。
输出
输出一个整数表示需要添加的最短的路径长度。
若果无论如何也无法使得所有的城市联通,输出 Concubines can’t do it. 。
样例:
input
5 3 2
1 2 1
1 3 2
1 4 3
2 3 4
2 5 5
output
5
理解:
最小生成树裸题。
前m个路径长度不用管,直接把城镇相连。
之后s个用结构体保存,排序之后选择,然后并查集莽一发就过了。
最小生成树 Kruscal
我先把修好的边加进去 然后没修的 排序 加边并且计算权值和 最后扫一遍并查集 是不是都加进去了,求和需要开longlong
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
#define INF 0x3f3f3f3f
int fa[maxn];
int init(int n){
for(int i=0;i<=n;i++)fa[i]=i;
}
int Find(int x){
return fa[x]==x?x:fa[x]=Find(fa[x]);
}
int Union(int a,int b){
int p1=Find(a),p2=Find(b);
fa[p2]=p1;
}
typedef struct edge{
int from,to,val;
}dege;
edge Edge[maxn];
edge dd[maxn];
bool cmp(edge a,edge b){
return a.val<b.val;
}
int n,m,s;
int main(){
scanf("%d%d%d",&n,&m,&s);
init(n);
for(int i=0;i<m;i++){
scanf("%d%d%d",&dd[i].from,&dd[i].to,&dd[i].val);
Union(dd[i].from,dd[i].to);
}
for(int i=0;i<s;i++){
scanf("%d%d%d",&Edge[i].from,&Edge[i].to,&Edge[i].val);
}
sort(Edge,Edge+s,cmp);
ll ans=0;
for(int i=0;i<s;i++){//依次选择最小的
if(Find(Edge[i].from)!=Find(Edge[i].to)){
Union(Edge[i].from,Edge[i].to);
ans+=Edge[i].val;
}
}
int cnt=0;
for(int i=1;i<=n;i++){
if(fa[i]==i)cnt++;
}
if(cnt>1) printf("Concubines can't do it.");
else printf("%lld",ans);
return 0;
}
![](https://dpic3.tiankong.com/tk/l1/QJ6634818103.jpg?x-oss-process=style/240h)