pku 1062 昂贵的聘礼 第一周训练——最短路

http://poj.org/problem?id=1062

这道题太让我纠结了。。才开始把提议理解错了,就是那个等级问题,我以为只要交易的双方的等级差异<=m就可以呢。结果样例过了无限的wa最后搜了一下解题报告才看懂个那个等级问题。他是交易的所有人的等级差异都要<=m才是满足条件的。。。唉。。枚举所有可能参与交易的对象+Dijkstra求最短路就可以了。。。可是在这里我就卡死了。。。有个问题使我不解也讨论了很久还是没发现。。

代码中见。。求解

View Code
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 107
#define inf 99999999
using namespace std;
bool vt[maxn],ok[maxn];
int dis[maxn],map[maxn][maxn],leval[maxn],val[maxn];
int n,m;
void init()//初始化
{
int i,j;
for (i = 0; i <= n; ++i)
{
for (j = 0; j <= n; ++j)
{
if (i == j) map[i][j] = 0;
else map[i][j] = inf;
}
}
}
int Dijkstra()
{
int i,j,k,min;
for (i = 1; i <= n; ++i)
{
dis[i] = inf;
vt[i] = false;
}
dis[1] = 0;
vt[1] = true;
/*
我开始是这样处理的,discuss里面的所有数据都过了,不过还是WA不解
求大牛解释
for (i = 1; i <= n; ++i)
{
dis[i] = map[1][i];
vt[i] = false;
}
vt[1] = true;
*/

for (k = 1; k <= n; ++k)
{
j = 1; min = inf;
for (i = 1; i <= n; ++i)
{
if (!vt[i] && ok[i] && dis[i] < min)
{
j = i; min = dis[i];
}
}
vt[j] = true;
for (i = 1; i <= n; ++i)
{
if (!vt[i] && ok[i] && dis[i] > dis[j] + map[j][i])
{
dis[i] = dis[j] + map[j][i];
}
}
}
int M = dis[1] + val[1];
for (i = 2; i <= n; ++i)//枚举出1所能到达的最近点
{
int c = dis[i] + val[i];
if (c < M)
M = c;
}
return M;
}
int main()
{
int i,j,x,pos,value;
scanf("%d%d",&m,&n);
init();
for (i = 1; i <= n; ++i)//建图
{
cin>>val[i]>>leval[i]>>x;
for (j = 0; j < x; ++j)
{
cin>>pos>>value;
map[i][pos] = value;
}
}
int t = leval[1];
int ans = inf;
for (i = 0; i <= m; ++i)
{
memset(ok,false,sizeof(ok));
for (j = 1; j <= n; ++j)//枚举等级符合的点
{
if (leval[j] >= t - m + i && leval[j] <= t + i)
ok[j] = true;
}
int c = Dijkstra();
if (ans > c) ans = c;
}
printf("%d\n",ans);
return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值