最短路_POJ_1062

来源:互联网 发布:索尼nex5r网络设置 编辑:程序博客网 时间:2024/06/08 00:48
/*很明显这个可以跑一个最短路,1出发到n个点的价值距离,取最小即为答案,但是,有一个问题,就是等级限制m如果起点等级为L1,那么他接下来能访问的是[L1-m, L1+m],假设他接下来访问了L2, L2下面可以访问[l2-m,l2+m]显然,这应该是两个区间取交集[Max(L1,L2)-m, Min(L1,L2)+m]为接下来可以访问的但是酱紫处理不了一种情况,就是1-3-4是最短,但是1-2-3把三给截断了,具体看样例5其实可以酱紫考虑,枚举可换的区间,例如开始是5,等级限制为2,那么能环的区间为[3,5],[4,6],[5,7]无外乎这三种即酋长为rank, 限制为m,枚举rank-m 到rank*/#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define oo 0x3f3f3f3f#define Max(a,b) (a)>(b)?(a):(b)#define Min(a,b) (a)<(b)?(a):(b)const int maxn = 105;using namespace std;int mp[maxn][maxn];int rank1[maxn],value[maxn];int m,n,p,l,x,t,v;queue<int>que;int dis[maxn],vis[maxn];int Abs(int x){    if(x<0)return -x;    return x;}int SPFA(int s,int mi, int mx){    while(!que.empty())que.pop();    for(int i = 1; i <= n; i++)    {        dis[i] = oo;        vis[i] = 0;    }    dis[s] = 0;    vis[s] = 1;    que.push(s);    while (!que.empty())    {        int u = que.front();        que.pop();        vis[u] = 0;        for(int v = 1; v <= n; v++)        {            if(mp[u][v]!=oo&&(rank1[v]>=mi&&rank1[v]<=mx))//            {                if((dis[v]>dis[u]+mp[u][v]))                {                    dis[v] = dis[u]+mp[u][v];                    if(!vis[v])                    {                        vis[v] = 1;                        que.push(v);                    }                }            }        }    }    int ans = dis[1]+value[1];    for(int i = 2; i <= n; i++)        ans = Min(ans, dis[i]+value[i]);    return ans;}int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d%d",&m,&n)!=EOF)    {        for(int i = 1; i <= n; i++)        {            mp[i][i] = 0;            for(int j = 1; j <= n; j++)                mp[i][j] = oo;        }        for(int i = 1; i <= n; i++)        {            scanf("%d%d%d",&p,&l,&x);            value[i] = p;            rank1[i] = l;            while(x--)            {                scanf("%d%d",&t,&v);                mp[i][t] = v;            }        }        int ret = oo;        for(int i = rank1[1]-m; i<= rank1[1]; i++)        {            ret = Min(ret, SPFA(1,i,i+m));        }        printf("%d\n",ret);    }    return 0;}/*测试数据1:1 410000 3 22 80003 50001000 2 14 2003000 2 14 20050 2 05250测试数据2:1 510000 3 42 30003 20004 20005 90008000 2 33 50004 20005 70005000 1 02000 4 15 190050 1 04000测试数据3:3 810000 3 62 30003 20004 20005 90007 10008 50088000 2 33 50004 20005 70005000 1 16 10002000 4 15 190050 1 05000 1 17 40072000 4 15 190080 3 02950测试数据4:1 101324 0 01234 0 0255 0 067 0 056 0 02134 0 0456 0 02345 0 067 0 06436 0 01324测试数据5:1 410000 3 22 13 31000 2 24 13 11000 3 14 2100 4 0105测试数据6:3 510000 3 42 30003 20004 20005 90008000 2 33 50004 20005 70005000 1 02000 4 15 190050 1 03950*/
0 0
原创粉丝点击