1. 程式人生 > >poj1062昂貴的聘禮

poj1062昂貴的聘禮

con 答案 ons can 得到 繪圖 cpp 。。 ret

這個題目我最開始看題目看了半天,看不懂。。

可是通過看例子及答案最終看懂了。

。。

首先先解決等級的關系。

。假設等級越界。則不能交換。。所以原本等級的界限是

[rank[1]-m,rank[1]+m],可是這個邊界裏面會出現等級僅僅差大於m。所以等級的區間應該是

[rank[1]-m,rank[1]],[rank[1]-m+1,rank[1]+1]............等等。所以一直枚舉到 [rank[1],rank[1]+m]..所以先通過枚舉得到能夠交換的點。

。然後就是題目的意思了。

我理解的優惠相當於是分解。

。。比方假設得到1號物品須要得到2號物品和8000金幣。不就相當於1號到2號號為單向路勁,權值為8000.。

。求各個點到1號點的最短路加上這個點的價值。。

如圖所看到的。

。。

1(10000)---------->2(1000)--------->4(50)

| 8000 200 |

|--------------------->3(3000)----------|

5000 200

繪圖之後一目了然。。。

然後運用dijkstra解決。

。。

。。

。。

希望各位指正我的想法。。

代碼例如以下:

#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
const int maxn=100+10;
int m,n;
int vis[maxn],dis[maxn],e[maxn][maxn];
int withtin[maxn],value[maxn],ranki[maxn];

int dijkstra()
{
    int tmp,now,i,j;
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    for(i=1;i<=n;i++)
    {
        tmp=INF;
        for(j=1;j<=n;j++)
        {
            if(!vis[j]&&withtin[j]&&dis[j]<tmp)
            {
                tmp=dis[j];
                now=j;
            }
        }
        vis[now]=1;
        for(j=1;j<=n;j++)
        {
            if(!vis[j]&&withtin[j]&&dis[j]>dis[now]+e[now][j])
                dis[j]=dis[now]+e[now][j];
        }
    }
    tmp=INF;
    for(i=1;i<=n;i++)
    {
        if(dis[i]+value[i]<tmp)
            tmp=dis[i]+value[i];
    }
    return tmp;
}


int main()
{
    int i,j,t,cost;
    int p,l,x,val,min_cost;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        memset(e,0x3f,sizeof(e));
        for(i=1;i<=n;i++)
             for(j=1;j<=n;j++)
            {
                if(i==j)
                e[i][j]=0;
            }
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&value[i],&ranki[i],&x);
            for(j=1;j<=x;j++)
            {
                scanf("%d%d",&t,&val);
                e[i][t]=val;
            }
        }
        min_cost=INF;
        for(i=0;i<=m;i++)
        {
            memset(withtin,0,sizeof(withtin));
            for(j=1;j<=n;j++)
            {
                if(ranki[j]>=ranki[1]-m+i&&ranki[j]<=ranki[1]+i)
                    withtin[j]=1;
            }
            cost=dijkstra();
             if(cost<min_cost)
                min_cost=cost;
        }
        printf("%d\n",min_cost);
    }
}


poj1062昂貴的聘禮