hdu1863(水)

又是一个被我写复杂的prim,发现

if(min==imax)

     break;

这一句可有可无


嗯,先是我写的后是prim

#include <iostream>

#define imax 100005

using namespace std;

#define INF 10000

int a[105][105],n,d[INF];

int pre[105],sum;

int lowcost[105],s[105],u;

int prim()

{

    int sum=0;

    for(int j=1;j<=n;j++)

        lowcost[j]=a[1][j];

    memset(s,0,sizeof(s));

    s[1]=1;

    for(int i=1;i<=n-1;i++)

    {

        int min=imax;

        for(int j=1;j<=n;j++)

        {

            if(s[j]==0&&min>lowcost[j])

            {

                min=lowcost[j];

                u=j;

            }

        }

       // if(min==imax)

       //     break;

        

        s[u]=1;

        sum=sum+lowcost[u];

        for(int j=1;j<=n;j++)

        {

            if(lowcost[j]>a[u][j]&&s[j]==0)

                lowcost[j]=a[u][j];

        }

    }

    return sum;

}

int find(int x)

{

    int r=x;

    while(pre[r]!=r)

        r=pre[r];

    int i=x,j;

    while(pre[i]!=r)

    {

        j=pre[i];

        pre[i]=r;

        i=j;

    }

    return r;

}

void mix(int x,int y)

{

    int r=find(x);

    int l=find(y);

    if(l!=r)

        pre[l]=r;

}


int main()

{

    int i,j,w,m;

    while(scanf("%d %d",&m,&n))

    {

        if(m==0)

            break;

        for(i=1;i<=n;i++)

            for(j=1;j<=n;j++)

                a[i][j]=100005;

        for(int k=0;k<m;k++)

        {

            scanf("%d %d %d",&i,&j,&w);

            a[i][j]=a[j][i]=w;

        }

        for(int i=1;i<=n;i++)

            pre[i]=i;

        for(int i=1;i<=n;i++)

        {

            for(int j=i+1;j<=n;j++)

                if(a[i][j]!=100005)

                    mix(i,j);

        }

        int sum=0;

        for(int i=1;i<=n;i++)

            if(pre[i]==i)

                sum++;

        if(sum>1)

            printf("?\n");

        else

        {

            int result=prim();

            cout<<result<<endl;

        }

    }

    return 0;

}


#include <iostream>

#include <cstring>

#define INF 999999999

using namespace std;


int map[105][105],visit[105],dis[105],M;

int prim()

{

    for(int i = 1;i <= M; i++)

    {

        dis[i] = map[i][1];

    }

    dis[1] = 0;

    visit[1] = 1;

    int sum = 0;

    for(int i = 1; i <= M-1; i++)

    {

        int temp = INF,pos;

        for(int j= 1; j <= M; j++)

        {

            if(!visit[j] && temp > dis[j])

            {

                temp = dis[j];

                pos = j;

            }

        }

        cout<<temp<<endl;

        if(temp == INF)

            return 0;

        visit[pos] = 1;

        sum += dis[pos];

        for(int j = 1; j <= M; j++)

        {

            if(!visit[j] && map[pos][j] < dis[j] && map[pos][j]!=INF)

            {

                dis[j] = map[pos][j];

            }

        }

    }

    return sum;

}

int main()

{

    int N;

    while(scanf("%d%d",&N,&M),N)

    {

        int u,v,w;

        memset(map,0x3f,sizeof(map));

        memset(dis,0x3f,sizeof(dis));

        memset(visit,0,sizeof(visit));

        for(int i = 1; i <= N; ++i)

        {

            scanf("%d%d%d",&u,&v,&w);

            map[u][v] = map[v][u] = w;

        }

        int ans = prim();

        if(ans)

            printf("%d\n",ans);

        else

            printf("?\n");

    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值