您的位置:首页 > 其它

POJ1062---昂贵的聘礼(最短路:题意。。)

2017-07-04 16:11 459 查看
【题目来源】https://vjudge.net/problem/POJ-1062

【题意】

题意很简单,就是要求买1号的东西,但是可以用规定的其他编号的东西代替,然后给出一个降低后的价格,但是呢,每件物品的主任具有等级的差距,也就是如果和等级4的交易后,若最大等级差距为2,那么任何情况下都不能再于等级1的交易。

【思路】

枚举一下差距的上限,因为如果一旦和等级4的交易了,若等级差距为2,那么在之后都不能与等级1的进行交易,所以要枚举。

我用的bellman,记录的是u,v端点的最多省多少钱,然后,找出最省钱的(一定是个负值)。

【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
struct pp
{
int u,v,w;
}edge[10001];
int ranks[101];
int mp[101][101];
int p[101];
int d[101];
int n,m,tot;

void add(int u,int v,int w)
{
edge[tot].u = u;
edge[tot].v = v;
edge[tot++].w = w;
}

int BellMan(int h,int l)
{
int u,v,w,mn=0;
memset(d,INF,sizeof(d));
d[1] = 0;
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < tot; ++j)
{
u = edge[j].u;
v = edge[j].v;
w = edge[j].w;
if(d[v] > d[u] + w && ranks[v] >= l && ranks[v] <= h)
{
d[v] = d[u] +w;
if(d[v]<mn)
mn=d[v];
}
}
}
return mn;
}
int main()
{
tot = 0;
int x,v,l,w;
scanf("%d %d",&m,&n);
memset(mp,INF,sizeof(mp));
int minn = 0;
for(int i = 1; i <= n; ++i)
{
scanf("%d %d %d",&p[i],&ranks[i],&x);
while(x--)
{
scanf("%d %d",&v,&w);
add(i,v,w);
}
}
for(int i=0;i<tot;i++)//求能省多少钱
{
edge[i].w-=p[edge[i].u];
edge[i].w+=p[edge[i].v];
}
for(int h = ranks[1]+m,l = ranks[1]; h >= ranks[1]; --h,--l)//枚举范围
{
minn = min(minn,BellMan(h,l));
}
printf("%d\n",minn+p[1]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: