L2-4 你才菜到家了 (25 分)

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/";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值