您的位置:首页 > 其它

POJ 1062 昂贵的聘礼 (分段dijkstra)

2017-02-14 14:19 417 查看

思路:

有题目可知最终1号一定要在交易链中,所有可以通过1号的等级来划分出一些等级区间。

现在假设1号等级为v,等级区间的差为m,那么我们可以知道最终结果一定在 [v−m,v+m] 中,但是不能直接用这个区间去判定,因为这个区间长度大于了m,所以我们从 [v−m,v] 开始,

for(int i = 0;i <= m;i++){
[v-m+i,v+i]
}


每次只对在这个等级区间里点进行dijkstra,然后就没有什么卡点了。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>

using namespace std;

int rank[110];
int cost[110];// 一开始单独买的花费
int within[110];
int vis[110];
int dist[110];
int ma[110][110];
int m,n;

struct node{
int n,v;
node(){}
node(int nn,int vv){
n = nn ,v = vv;
}
};

bool operator < (const node& a,const node& b){
return a.v > b.v;
}

void dijkstra(){
priority_queue<node> q;
int pos;
for(int i = 1;i <= n;i++){
if(within[i] == 1){
q.push(node(i,dist[i]));
}
}

node te;
while(!q.empty()){
te = q.top();
if(vis[te.n] == 1){
q.pop();
continue;
}
else
vis[te.n] = 1;
q.pop();
for(int i = 1;i <= n;i++){
if(within[i] && !vis[i] && dist[te.n] + ma[te.n][i] < dist[i]){
dist[i] = dist[te.n] + ma[te.n][i];
q.push(node(i,dist[i]));
}
}

}
}

int main(){
cin>>m>>n;
memset(ma,0x3f,sizeof(ma));
for(int i = 1; i <= n;i++){
ma[i][i] = 0;
}
int a,b;
for(int i = 1;i <= n;i++){
int jj;
scanf("%d%d%d",&cost[i],&rank[i],&jj);
for(int j = 1;j <= jj;j++){
scanf("%d%d",&a,&b);
ma[a][i] = b;
}
}

int v = rank[1];
int ans = 0x3f3f3f3f;
for(int i = 0;i <= m;i++){
memset(within,0,sizeof(within));
memset(vis,0,sizeof(vis));
for(int j = 1;j <= n;j++){
if(rank[j] >= v-m+i && rank[j] <= v+i)
within[j] = 1;
}
for(int i = 1;i <= n;i++){
dist[i] = cost[i];
}
dijkstra();
if(ans > dist[1])
ans = dist[1];
}
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: