这是一道很有意思,也很坑的题。
我是以每个部落的人为节点,以他能交易的东西为边。
等级的判断非常重要,枚举的时候,交易双方的等级都必须在范围内。
测试数据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;
}