prim8,9,10TLE,如何优化 求助

P3366 【模板】最小生成树

Harnue @ 2022-02-17 20:50:16

#include<iostream>

#include<cmath>
#include<cstring>
#include<iomanip>
#include<set>

#define N 9009
#define M 400009
#define inf pow(2,31)-1
#define rep(i,m,n) for(int i=m;i<=n;++i) 
using namespace std;
typedef long long ll;

int n,m,s,ans=0,num_edge=0,flag=1,head[N],isa[N];//head[i],表示以i为起点的最后一条边在边集数组的位置(编号)
set<int>a,b;

struct Edge
{
    int next,to,w;//终点,边权,同起点的上一条边的编号
}edge[M]; 

void addedge(int from,int to,int w) 
{ 
    edge[++num_edge].next=head[from]; 
    edge[num_edge].to=to; 
    edge[num_edge].w=w; //以u为起点上一条边的编号,也就是与这个边起点相同的上一条边的编号
    head[from]=num_edge; //更新以u为起点上一条边的编号
}

void init(int n)//初始化
{
    rep(i,1,n) 
    {
        head[i]=-1;
        a.insert(i);
        isa[i]=1;
    }
}

int main()
{
    ll min=0;
    cin>>n>>m;
    init(n);
    rep(i,1,m)
    {
        int from,to,w;
        cin>>from>>to>>w;
        addedge(from,to,w);
        addedge(to,from,w);
    }

    a.erase(1);
    b.insert(1);
    isa[1]=0;

    while(!a.empty())
    {
        int v;
        min=inf;
        for(set<int>::iterator it=b.begin();it!=b.end();it++)//n个起点
        {

            for (int j = head[*it]; j != -1; j = edge[j].next)//遍历以i为起点的边
            {
                if(isa[edge[j].to] && edge[j].w<min) 
                {
                    min=edge[j].w;
                    v=edge[j].to;
                }
            }
        }
        if(min==inf) 
        {
            flag=0;
            break;
        }
        ans+=min;

        a.erase(v);
        isa[v]=0;
        b.insert(v);

    }

    if(flag) cout<<ans;
    else cout<<'o'<<'r'<<'z';

    return 0;
}

by RockyYue @ 2022-02-17 20:56:09

珂以试试堆优化


by CrazyBox @ 2022-02-19 17:10:24

你要不试试是不是进入死循环了?


|