A - 畅通工程 HDU - 1863(prim+堆优化)

题目戳我

最小生成树我就只学了kruskal,不要问我为什么,只因为他更好理解容易写,所以偷懒只学了他,结果今天写题的时候发现需要用prim算法,我也是很无语,写了个入门题,也算是个板子题吧?来水一篇博客。至于你想看详细的题解的话就去看其他博主吧。

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define lson num<<1
#define rson num<<1|1
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 3e5+ 50;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const ll  lnf  = 0x3f3f3f3f3f3f3f3f;
const ll mod = 23333;
const  double pi=3.141592653589;
int n,m,cnt,head[10005],dis[10005],vis[10005];
struct node
{
    int to,next,w;
}a[10005];
void add(int u,int v,int w)
{
    a[++cnt].to=v;
    a[cnt].w=w;
    a[cnt].next=head[u];
    head[u]=cnt;
}
int count1;
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int> > >q;//使堆顶的元素最小,注意>>这个符号要写出> >,也就是加一个空格,不然容易报错
void prim()
{
    int ans=0;
    dis[1]=0;
    q.push({0,1});
    while(!q.empty()&&count1<m)
    {
        int d=q.top().first,u=q.top().second;//每次取最小的元素
        q.pop();
        if(vis[u])continue;
        count1++;
        ans+=d;
        vis[u]=1;
        for(int i=head[u];~i;i=a[i].next)
        {
            if(a[i].w<dis[a[i].to])
            {
                dis[a[i].to]=a[i].w;
                q.push({dis[a[i].to],a[i].to});
            }
        }
    }
    if(count1==m)
    {
        printf("%d\n",ans);
    }
    else
    {
        printf("?\n");
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cnt=0;
        count1=0;
        ms(dis,inf);
        ms(head,-1);
        ms(vis,0);
        if(n==0)break;
        for(int i=1;i<=n;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        if(n<m-1)//如果所有路加起来小于点的个数-1那么不可能构成连通图,自己画图想想就知道了
        {
            printf("?\n");
            continue;
        }
        prim();
    }
    return 0;
}

0当然这个题目也可以不用堆优化反正就这么大的数据

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define lson num<<1
#define rson num<<1|1
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 3e5+ 50;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const ll  lnf  = 0x3f3f3f3f3f3f3f3f;
const ll mod = 23333;
const  double pi=3.141592653589;
int n,m,cnt,head[10005],dis[10005],vis[10005];
struct node
{
    int to,next,w;
}a[10005];
void add(int u,int v,int w)
{
    a[++cnt].to=v;
    a[cnt].w=w;
    a[cnt].next=head[u];
    head[u]=cnt;
}
int count1;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
void prim()
{
    dis[1]=0;
    for(int i=head[1];~i;i=a[i].next)
    {
        dis[a[i].to]=min(dis[a[i].to],a[i].w);
    }
    int ans=0;
    int num=0;
    bool flage=true;
    for(int i=1;i<=m;i++)
    {
        int mi=inf;
        int pos=-1;
        for(int j=1;j<=m;j++)
        {
            if(!vis[j]&&mi>dis[j])
            {
                mi=dis[j];
                pos=j;
            }
        }
        if(pos==-1)
        {
            flage=false;
            break;
        }
        vis[pos]=1;
        ans+=mi;
        for(int j=head[pos];~j;j=a[j].next)
        {
            if(!vis[a[j].to]&&a[j].w<dis[a[j].to])
            {
                dis[a[j].to]=a[j].w;
            }
        }
    }
    if(flage)
    {
        printf("%d\n",ans);
    }
    else
    {
        printf("?\n");
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cnt=0;
        count1=0;
        ms(dis,inf);
        ms(head,-1);
        ms(vis,0);
        if(n==0)break;
        for(int i=1;i<=n;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        prim();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qcccc_/article/details/107382955
今日推荐