昂贵的聘礼

来源:互联网 发布:查找数组最大值最小值 编辑:程序博客网 时间:2024/06/06 00:33

F题倒过来单向给数组赋值,如money[4][3]表示有了4物品得到3物品需要给的金钱,0为超级起点,money[0][1]表示直接得到1物品需要的金钱,图构建好了,我也是用Floyd算法直接计算得到1物品需要的最少金钱。但是我调试了很多次也没找出来哪里错了。

#include <iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#define INF 9999999
using namespace std;
struct goods
{
    int price,level,repnum,need[105];
}a[105];


int main()
{
    int allnum,limit,charge,num,b[105],i,j=0,money[105][105],k;
    scanf("%d%d",&limit,&allnum);
    memset(a,0,sizeof(a));
    for(i=0;i<=allnum;i++)
    {
        for(j=0;j<=allnum;j++)
        {
             money[i][j]=(i==j?0:INF);
        }
    }
    for(i=1;i<=allnum;i++)
    {
        scanf("%d%d%d",&a[i].price,&a[i].level,&a[i].repnum);
        for(j=0;j<a[i].repnum;j++)
        {
            scanf("%d%d",&num,&charge);
            b[num]=charge;
a[i].need[num]=1;
        }
    }
    for(i=allnum;i>0;i--)
        {
            for(j=i-1;j>0;j--)
            {
                if(fabs(a[1].level-a[i].level)<=limit&&a[j].need[i]==1)
                {
money[i][j]=b[i];
}
            }
        }
        for(i=0,j=1;j<=allnum;j++)
        {
            money[i][j]=a[j].price;          
        }
for(k=0;k<=allnum;k++)
{
            for(i=0;i<=allnum;i++)
{
for(j=0;j<=allnum;j++)
{
if(money[i][j]>money[i][k]+money[k][j])
money[i][j]=money[i][k]+money[k][j];
}
}
}
    printf("%d\n",money[0][1]);
    return 0;
}

用Floyd暂时还没有写出来,但是仿照着别人的dij算法把这道题做了主要欠考虑的地方是等级范围,应该是(k-m,k),中间只应该有m个数,而不是(k-m,k+m)

#include <iostream>                         //dij算法昂贵的聘礼

#include<cstring>

#include<cstdio>

#define INF 0x7f7f7f7f

#define maxn 1005

 

using namespace std;

int dis[maxn];

bool vis[maxn];

int money[maxn][maxn];

int limit,allnum,charge,num,price[maxn],level[maxn],rep[maxn];

void init()

{

    memset(dis,INF,sizeof(dis));

    memset(vis,false,sizeof(vis));

    memset(money,INF,sizeof(money));

}

int dij()

{

    dis[0]=0;

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

        dis[i]=money[0][i];

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

    {

        int minn=INF,x;

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

        {

            if(!vis[j]&&dis[j]<=minn)

                minn=dis[x=j];

        }

        vis[x]=true;

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

        {

            if(!vis[j]&&dis[j]>dis[x]+money[x][j])

                dis[j]=dis[x]+money[x][j];

        }

    }

    return dis[1];

 

}

 

int main()

{

    while(~scanf("%d%d",&limit,&allnum))

    {

        init();

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

        {

            scanf("%d%d%d",&price[i],&level[i],&rep[i]);

            for(int j=0;j<rep[i];j++)

            {

                scanf("%d%d",&num,&charge);

                money[num][i]=charge;

            }

            money[0][i]=price[i];

        }

        int ans=INF;

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

        {

            int k=level[i];

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

            {

                if(level[j]-k>limit||k>level[j])            //范围是(k-m,k)

                    vis[j]=true;

                else vis[j]=false;

            }

            int now=dij();

            ans=min(now,ans);

        }

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

    }

    return 0;

}




0 0
原创粉丝点击