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

来源:互联网 发布:泰安广电网络怎么样 编辑:程序博客网 时间:2024/05/09 14:30

思路:

有题目可知最终1号一定要在交易链中,所有可以通过1号的等级来划分出一些等级区间。
现在假设1号等级为v,等级区间的差为m,那么我们可以知道最终结果一定在 [vm,v+m] 中,但是不能直接用这个区间去判定,因为这个区间长度大于了m,所以我们从 [vm,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);}
1 0
原创粉丝点击