poj1062昂贵的聘礼(迪杰斯特拉)

这道题我一共见过三次,直到这次才费了好大的劲做出来,太恶心了,希望有生之年不要再碰到这个题
这道题需要注意几个点:
1.酋长不一定是最高等级,可能有他爸爸,他爷爷之类的。。。。。你懂得
2.不能以酋长为圆心画圆找整个圆,不能找直径区间,因为可能酋长满足条件,但是酋长的上限和下限两者超出了等级的限制,我在这个点上卡了好久,本来假期就知道这个点是错的,结果又错了
3.我这个是把所有点枚举了一遍,也可以找半径区间,然后枚举区间,可能会时间复杂度更低一点

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#define INF 1000005

using namespace std;

const int maxn=105;
int m,n;
int cost[maxn][maxn];
int dis[maxn];
int r[maxn];
int next[maxn];          ///第i号物品的替代总数
bool use[maxn];
void dijk()
{
    int node;
    int sd;
    for(int i=1; i<=n; i++)
    {
        dis[i]=cost[0][i];
    }
    for(int i=1; i<=n; i++)
    {
        node=0;
        sd=INF;
        for(int j=1; j<=n; j++)
        {
            if(!use[j]&&sd>dis[j])
            {
                sd=dis[j];
                node=j;
            }
        }
        if(node==0) break;//循环结束条件
        use[node]=true;
        for(int j=1; j<=n; j++)
        {
            if(!use[j]&&cost[node][j]<INF)
            {
                dis[j]=min(dis[j],dis[node]+cost[node][j]);
            }
        }
    }
}
int main()
{
    while(cin>>m>>n)
    {
        for(int i=1; i<=n; i++)
            dis[i]=INF;
        memset(r,0,sizeof(r));
        memset(next,0,sizeof(next));
        memset(use,0,sizeof(use));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                if(i==j)
                    cost[i][j]=0;
                else cost[i][j]=INF;
            }
        for(int i=1; i<=n; i++)
        {
            cin>>cost[0][i]>>r[i]>>next[i];//多了一个点0
            for(int j=1; j<=next[i]; j++)
            {
                int t,u;
                cin>>t>>u;
                cost[t][i]=u;
            }
        }
        int maxn;
        int minn=INF;
        for(int i=1; i<=n; i++)
        {
            maxn=r[i];
            for(int j=1; j<=n; j++)
            {
                if(r[j]>maxn||maxn-r[j]>m)//把每个点当做最高等级,往下找不在等级范围内的点,赋成true
                {
                    use[j]=true;
                }
                else use[j]=false;
            }
            dijk();//最短路要跑很多遍
            minn=min(minn,dis[1]);
        }
        cout<<minn<<endl;

    }
    return 0;
}

你可能感兴趣的:(poj,图论)