poj 图相关之1062 昂贵的聘礼

来源:互联网 发布:软件研发绩效考核制度 编辑:程序博客网 时间:2024/06/10 12:14

poj 图相关之1062 昂贵的聘礼
Dijkstra+枚举
Accepted 180K 16MS
基本上是看别人的算法做出来的,这道题主要注意以下几点
1、W[i][j]权重设置为i到j的钱,W[i][i]=0,其余的设置为无限大,然后就是正常的Dijkstra算法,dis首先都设置为无限大,除了dis1

//首先循环N次,如果有N个顶点的话for (i = 0; i < N; i++)//循环n次    {        tmp = INF;        //选出最小dis的下标k        for (j = 1; j <= N; j++)        {            if (!mark[j] && dis[j] <= tmp&&CanChange[j])            {                k = j;                tmp = dis[j];            }        }        //k标记为true        mark[k] = 1;        //更新通过k为中介点更新源点到其他点的路径        for (j = 1; j <= N; j++)        {            if (!mark[j] && dis[j]>dis[k] + W[k][j])            {                if (CanChange[j])                    dis[j] = dis[k] + W[k][j];            }        }    }

2、这道题非常重要的是枚举的过程,假设king-level=4和limit-level=2,那么对于图中的点而言可以更新的level范围有2-4,3-5,4-6;前提是保证level的max-min<=limit-level,同时king-level也在范围中。
3、最后输出的最小值是dis[i]+value[i]的最小值,每个节点还有权值(表示假设不继续往下走需要付多少金币)
代码:

#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<math.h>#include<algorithm>#include<memory.h>#include<vector>#include<queue>#include<map>#define MAXNUM 110#define INF 200000000;using namespace std;int W[MAXNUM][MAXNUM], value[MAXNUM], Level[MAXNUM], dis[MAXNUM], M, N;bool CanChange[MAXNUM], mark[MAXNUM];int Dijkstra(){    int i, j, k, tmp, mincost;    for (i = 1; i <= N; i++)        dis[i] = INF;    dis[1] = 0;    mincost = INF;    for (i = 0; i < N; i++)//循环n次    {        tmp = INF;        for (j = 1; j <= N; j++)        {            if (!mark[j] && dis[j] <= tmp&&CanChange[j])            {                k = j;                tmp = dis[j];            }        }        mark[k] = 1;        for (j = 1; j <= N; j++)        {            if (!mark[j] && dis[j]>dis[k] + W[k][j])            {                if (CanChange[j])                    dis[j] = dis[k] + W[k][j];            }        }    }    for (i = 1; i <= N; i++)    {        dis[i] += value[i];        mincost = min(mincost, dis[i]);    }    return mincost;}int main(){    //freopen("1.txt", "r", stdin);    int i, j, k, a, b, maxlevel, cost;    scanf("%d%d", &M, &N);    maxlevel = M;    for (i = 1; i <= N; i++)    for (j = 1; j <= N; j++)        W[i][j] = INF;    for (i = 1; i <= N; i++)        W[i][i] = 0;    for (i = 1; i <= N; i++)    {        scanf("%d%d%d", &value[i], &Level[i], &k);        for (j = 0; j < k; j++)        {            scanf("%d%d", &a, &b);            W[i][a] = b;        }    }    cost = value[1];    for (i = 0; i <= maxlevel; i++)    {        memset(mark, 0, sizeof(mark));        memset(CanChange, 0, sizeof(CanChange));        for (j = 1; j <= N; j++)        {            if (Level[j] >= Level[1] - maxlevel+ i && Level[j] <= Level[1] + i)                CanChange[j] = true;        }        cost = min(cost, Dijkstra());    }    printf("%d\n", cost);}
原创粉丝点击