poj1062 Bellman 昂贵的聘礼

题目链接:点击打开链接

这是一道很有意思,也很坑的题。

我是以每个部落的人为节点,以他能交易的东西为边。

等级的判断非常重要,枚举的时候,交易双方的等级都必须在范围内。

附上大牛的测试数据
测试数据1:  
1 4  
10000 3 2  
2 8000  
3 5000  
1000 2 1  
4 200  
3000 2 1  
4 200  
50 2 0  
  
5250  
  
测试数据2:  
1 5  
10000 3 4  
2 3000  
3 2000  
4 2000  
5 9000  
8000 2 3  
3 5000  
4 2000  
5 7000  
5000 1 0  
2000 4 1  
5 1900  
50 1 0  
  
4000  
测试数据3:  
3 8  
10000 3 6  
2 3000  
3 2000  
4 2000  
5 9000  
7 1000  
8 5008  
8000 2 3  
3 5000  
4 2000  
5 7000  
5000 1 1  
6 1000  
2000 4 1  
5 1900  
50 1 0  
5000 1 1  
7 4007  
2000 4 1  
5 1900  
80 3 0  
  
2950  
测试数据4:  
1 10  
1324 0 0  
1234 0 0  
255 0 0  
67 0 0  
56 0 0  
2134 0 0  
456 0 0  
2345 0 0  
67 0 0  
6436 0 0  
  
1324  
  
测试数据5:  
1 4  
10000 3 2  
2 1  
3 3  
1000 2 2  
4 1  
3 1  
1000 3 1  
4 2  
100 4 0  
  
105  
测试数据6:  
3 5  
10000 3 4  
2 3000  
3 2000  
4 2000  
5 9000  
8000 2 3  
3 5000  
4 2000  
5 7000  
5000 1 0  
2000 4 1  
5 1900  
50 1 0  
  
3950 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
struct ab{
    int u,v,p;//r:等级
}ex[25500];
int node[25500],ranks[25500],rankg[25500];
int n,m,w,cnt;
int bellman(int le){
    int check;
    int dis[25500];
    memset(dis,1,sizeof(dis));
    dis[1]=node[1];

    for(int k=1; k<=n-1; k++) //算法核心
    {
        check=0;

        for(int i=1; i<=cnt; i++)
            if((ranks[ex[i].v]<=m+le&&ranks[ex[i].v]>=le)&&(ranks[ex[i].u]<=m+le&&ranks[ex[i].u]>=le)&&dis[ex[i].v]>dis[ex[i].u]+ex[i].p+node[ex[i].v]){
                dis[ex[i].v]=dis[ex[i].u]+ex[i].p+node[ex[i].v];   //交易的双方都必须在范围内
                check=1;
            }  //进行松弛操作

        if(check==0) break;//检测dis是否有更新,没有就退出循环
        //for(int i=1; i<=cnt; i++) printf("%d ",dis[i]); printf("\n");
    }

    int mins=99999999;
    for(int i=1; i<=cnt; i++){
        if(mins>dis[i])
            mins=dis[i];
    }
    return mins;
}
int main()
{
    int p,l,x,t,v;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        memset(ex,0,sizeof(ex));
        memset(node,0,sizeof(node));
        cnt=1;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&p,&l,&x);
            node[i]=p; ranks[i]=l;
            for(int j=1;j<=x;j++){
                scanf("%d%d",&t,&v);
                ex[cnt].u=i;
                ex[cnt].v=t;
                ex[cnt].p=(v-p); //建图,边为负权
                cnt++;
            }
        }
        int minsum=9999999;
        for(int i=ranks[1]-m;i<=ranks[1];i++){ //枚举等级范围,取最小
            //cout<<rankg[i]<<endl;
            int ss=bellman(i);
            if(ss<minsum) minsum=ss;
        }


            printf("%d\n",minsum);
    }
    return 0;
}

阅读更多
文章标签: 最短路 bellman
个人分类: 最短路
相关热词: poj1062
上一篇HDU 6024 Building Shops 区间dp
下一篇进程调度过程的模拟——时间轮转法 c++实现
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭