点
1.按字典序最小的顺序排列合起来的字符串的字典序最小,显然
2.就你判断它到底能不能生成一个最小生成树,你有两种方法
(1)加一次边就cnt++,到最后如果cnt<n-1,就代表是不可以生成最小生成树(n是总点数)
(2)从头到尾用find函数再次找一下父亲结点,如果父亲结点等于本身的结点不止一个,那么就不能生成一个最小生成树。因为你一个最小生成树就只有一个根结点。
3.排序的第二权重用a.name+b.name<b.name+a.name?到时候试一下,直接用那个可不可以,直接用a.name<b.name的话会少得一些分数,不清楚是为啥,反正如果它可以直接这样排序的话,那就直接排序好一点。
嗯懂了
一个例子
42420
42042
如果按照字典序的话就是42420,但是其实这样拼接起来不会是最小的。
所以排序的时候你得用42042
也就是
a.name+b.name<b.name+a.name
问题
1.排序的时候那个字典序的顺序弄错了。
2.输入的时候你的顺序反掉了,你要看它题目的输入顺序的啊!!
2.最后输出答案的时候忘记再次排序了
3.vector的排序是sort(ans.begin(),ans.end())
4.mn你又弄混了,这一点你要特别特别注意!!
代码
24分代码
这个不清楚为啥那个非连通图的判断是有问题的少了1分,反正差不多是对的hh
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int M=2e5+10;
int n,m,p[N];
vector<string> ans;
struct edge{
string name;
int a,b,w;
}edges[M];
bool cmp(edge a,edge b){
if(a.w!=b.w){
return a.w<b.w;
}
else{
return a.name+b.name<b.name+a.name;
}
}
int find(int x){
if(p[x]!=x){
p[x]=find(p[x]);
}
return p[x];
}
int kruskal(){
sort(edges,edges+m,cmp);
for(int i=0;i<=n;i++){
p[i]=i;
}
for(int i=0;i<m;i++){
int j=edges[i].a;
int k=edges[i].b;
int l=edges[i].w;
string na=edges[i].name;
j=find(j);
k=find(k);
if(j!=k){
p[j]=k;
ans.push_back(na);
}
}
}
int main(){
cin>>n>>m;
string name;
int a,b,w;
for(int i=0;i<m;i++){
cin>>name>>w>>a>>b;
edges[i].name=name;
edges[i].a=a;
edges[i].b=b;
edges[i].w=w;
}
kruskal();
int c=0;
for(int i=1;i<=n;i++){
int f=find(i);
if(f==i){
c++;
}
}
if(c==1){
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++){
cout<<ans[i];
}
}
else{
cout<<"don't cout or printf me directly!!!!!!!\Orz/";
}
}