您的位置:首页 > 其它

POJ 1062 昂贵的聘礼

2013-08-06 16:55 176 查看
这题说实在话就是模版题,可是你要是不知道模版是怎么工作的,有模版也没用,这个题就是个例子。

所以说这个题给了我个教训就是:有了模版也得自己敲,要不然关键时刻是不管用的。

这个题的关键在于:

1、虚拟一个节点0,所有物品的价值被表示为这个点到对应物品编号点的边的权值。

2、相关联的物品连一条权为优惠价格的边。

3、求节点0与节点1之间的最短路就行了。

要注意的的是:

1、酋长不一定是最高级,所以控制交易等级范围时不一定酋长是等级上界,需要对等级范围进行枚举。

2、交易等级范围就是等级差的大小,因为间接交易超过等级差也不行。

下面是代码:

#include <stdio.h>
const int V=105;
const int E=10005;
struct node
{
int mon,lv;
} wu[V];
struct node1
{
int u,v,w;
} edge[E];
int m,l,r,dis[V],vis[V];
void bellmam_ford(int n)
{
int i,j,flat;
for(i=0; i<n; i++)//初始化0点到各点的权值,及各物品的价值,dis[0]=0。
{
dis[i]=wu[i].mon;
}
flat=0;
for(i=1; i<=n; i++)
{
for(j=0; j<m; j++)
{
if(wu[edge[j].u].lv>=l&&wu[edge[j].u].lv<=r&&wu[edge[j].v].lv>=l&&wu[edge[j].v].lv<=r&&dis[edge[j].u]>dis[edge[j].v]+edge[j].w)
{
dis[edge[j].u]=dis[edge[j].v]+edge[j].w;
flat=1;
}
}
if(!flat)
{
break;
}
}
}
int main()
{
int M,N;
while(scanf("%d%d",&M,&N)!=EOF)
{
int i,j,t;
m=0;
for(i=1; i<=N; i++)//进行输入,建立有向边的邻接表。
{
scanf("%d%d%d",&wu[i].mon,&wu[i].lv,&t);
edge[m].u=0;
edge[m].v=i;
edge[m].w=wu[i].mon;
m++;
for(j=0; j<t; j++)
{
scanf("%d%d",&edge[m].v,&edge[m].w);
edge[m].u=i;
m++;
}
}
int min1=wu[1].mon;
wu[0].lv=wu[1].lv;
for(l=wu[1].lv-M; l<=wu[1].lv; l++)//枚举等级范围,范围长度为M。
{
r=l+M;
bellmam_ford(N+1);//因为多虚拟一个点,所以是n+1个点
if(min1>dis[1])
{
min1=dis[1];
}
}
printf("%d\n",min1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: