家~人~们,帮~帮~忙~啊~prim和kruskal一个也不对(┭┮﹏┭┮)

P3366 【模板】最小生成树

wangjiajinself @ 2023-11-26 17:20:11

#include <iostream>
using namespace std;
const int MAXN=5010;
const int INF=0x3f3f3f3f;
int g[MAXN][MAXN],dist[MAXN];
bool book[MAXN];
int n,m,res;
void prim()
{
    dist[1]=0;
    book[1]=true;
    for(int i=2;i<=n;i++)
    dist[i]=min(dist[i],g[1][i]);
    for(int i=2;i<=n;i++)
    {
        int temp=INF;
        int t=-1;
        for(int j=2;j<=n;j++)
            {
                if(!book[j]&&dist[j]<temp)
                {
                    temp=dist[j];
                    t=j;
                }
            }
            if(t==-1)
            {
                res=INF;
                return;
            }
            book[t]=true;
            res+=dist[t];
            for(int j=2;j<=n;j++)
            dist[j]=min(dist[j],g[t][j]);
    }

}
int main() {
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        g[i][j]=INF;
        dist[i]=INF;
    }
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        g[u][v]=g[v][u]=w;
    }
    prim();
    if(res==INF)
    cout<<"orz";
    else cout<<res;
    return 0;
}

prim对了仨点

#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=5010,MAXM=200010;
struct edge{
    int u,v,w;
}edges[MAXM];
int n,m,u,v,w,parent[MAXN];
void Ufset()
{
    for(int i=1;i<=n;i++)
    parent[i]=-1;
}
bool cmp(edge o,edge p)
{
    return o.w<=p.w;
}
int Find(int x)
{
    int s;
    for(s=x;parent[s]>0;s=parent[s]);
    //优化-压缩路径 
    while(s!=x)
    {
        int tmp=parent[x];
        parent[x]=s;
        x=tmp;
    }
    return s;
}
void Union(int R1,int R2)
{
    int r1=Find(R1),r2=Find(R2);
    if(r1>r2)
    parent[R1]=r2;
    if(r1<r2)
    parent[R2]=r1;
    /*
    int tmp=parent[r1]+parent[r2];
    if(parent[r1]>parent[r2])
    {
    parent[r1]=r2;
    parent[r2]=tmp;
    }
    else {
    parent[r2]=r1;
    parent[r1]=tmp;
    }
    */
}
void kruskal()
{
    int sum=0,num=0;
    for(int i=1;i<=m;i++)
    {
        if(Find(edges[i].u)!=Find(edges[i].v))//||Find(parent[edges[i].u])==-1
        {
            sum+=edges[i].w;
            num++;
            Union(edges[i].u,edges[i].v);
        }
        if(num>=n-1) break;
    }
    if(num<n-1) cout<<"orz";
    else cout<<sum;
}
int main() {
    cin>>n>>m;
    //n dian m bian
    Ufset();
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        edges[i].u=u;
        edges[i].v=v;
        edges[i].w=w;
    }
    sort(edges+1,edges+m+1,cmp);
    kruskal();
    return 0;
    //O(边数*log边数)
}

44分,还RE了几个

我太弱了


by linhao2010 @ 2023-11-26 17:31:02

我来

……

看见你这个名字,我瞬间感觉我不配……

(感到丢银(╥﹏╥))


by WilliamFranklin @ 2023-11-26 17:31:18

@noipquanguojinjiang kruskal 是因为 Ufset 写错了吧应该是

void Ufset()
{
    for(int i=1;i<=n;i++)
    parent[i]=i;
}

by wangjiajinself @ 2023-11-26 18:55:26

@linhao2010 额。。。日常发神经罢了()


by wangjiajinself @ 2023-11-26 19:01:47

@WilliamFranklin 还是不对┭┮﹏┭┮


by WilliamFranklin @ 2023-11-26 19:08:46

@noipquanguojinjiang 因为这是模板,所以看看我是怎么写的吧,可以学习一下:

#include<bits/stdc++.h>
using namespace std;
inline int read()
{  
    int s = 0, f = 1;  
    char ch = getchar();  
    while(!isdigit(ch)) {  
        if(ch == '-') f = -1; 
        ch = getchar(); 
    }  
    while(isdigit(ch)) {  
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();  
    }  
    return s * f;  
} 
struct node{
    int to;
    int from;
    int money;
}a[500005];
int fa[100005];
bool cmp(node b, node c) {
    return b.money < c.money;
}
void init(int n){
    for (int i = 1; i <= n; i++) {
        fa[i] = i;
    }
}
int find(int i) {
    if (i == fa[i]) {
        return i;
    } else {
        fa[i] = find(fa[i]);
        return fa[i];
    }
}
void w(int i, int j) {
    fa[find(i)] = find(j);
}
int main(){
    int n, m;
    n = read();
    m = read();
    int u, v, mo;
    init(n);
    for (int i = 1; i <= m; i++) {
        a[i].from = read();
        a[i].to = read();
        a[i].money = read(); 
        if(a[i].to == a[i].from){
            i--;
            m--;
        }
    }
    sort(a + 1, a + m + 1, cmp);
    int sum = 0;
    long long ans = 0;
    for (int i = 1; i <= m && sum < n; i++) {
        if(find(a[i].to) != find(a[i].from)){
            ans += a[i].money;
            w(a[i].to, a[i].from);
            sum++;
        }
    }
    if(sum != n - 1) {
        printf("orz");
    }
    else{
        printf("%lld", ans);
    }
}

by wangjiajinself @ 2023-11-26 20:13:21

@WilliamFrankl 谢谢


|