我是以0节点为起始,多设置一个n为终止的。
建的有向图和网上的标算好像方向是全反的,但是我觉得这完全不影响答案啊。
求大神指点!!!
或者有谁有poj数据的?给我自己测测啊啊啊啊
#include<iostream>
using namespace std;
#define MAX_INT 21474836;
struct node
{
int value;
int key;
};
node heap[150]; //堆
int map[110][110]; //图
int m, n;
int heapSize;
int dis[110]; //dijkstra的那个dis
int heapIndex[110]; //保存i节点在堆中的位置
int level[110]; //i节点的级别
int hashLevel[110];
int numHLevel;
void exchange(node* i, node* j)
{
node tmp = *i;
*i = *j;
*j = tmp;
}
//堆调整 向下
void downAdjHeap(int i)
{
while (i * 2 + 1 < heapSize)
{
int lc = i * 2 + 1;
int rc = i * 2 + 2;
if (lc < heapSize && rc < heapSize)
{
if (heap[lc].value > heap[rc].value)
{
if (heap[i].value > heap[rc].value)
{
exchange(&heap[i], &heap[rc]);
heapIndex[heap[i].key] = i;
heapIndex[heap[rc].key] = rc;
}
else
{
break;
}
}
else
{
if (heap[i].value > heap[lc].value)
{
exchange(&heap[i], &heap[lc]);
heapIndex[heap[i].key] = i;
heapIndex[heap[lc].key] = lc;
}
else
{
break;
}
}
}
else if (lc < heapSize)
{
if (heap[i].value > heap[lc].value)
{
exchange(&heap[i], &heap[lc]);
heapIndex[heap[i].key] = i;
heapIndex[heap[lc].key] = lc;
}
else
{
break;
}
}
}
}
//堆调整 向上
void upAdjHeap(int i)
{
while (i > 0)
{
int father = (i - 1) / 2;
if (heap[i].value < heap[father].value)
{
exchange(&heap[i], &heap[father]);
heapIndex[heap[i].key] = i;
heapIndex[heap[father].key] = father;
}
else
{
break;
}
}
}
//建堆
void buildHeap()
{
for (int i = (heapSize - 1) / 2; i >= 0; i--)
{
downAdjHeap(i);
}
}
node getHeapHead()
{
exchange(&heap[0], &heap[heapSize - 1]);
heapIndex[heap[0].key] = 0;
heapIndex[heap[heapSize - 1].key] = heapSize - 1;
heapSize--;
downAdjHeap(0);
return heap[heapSize];
}
void print()
{
for (int i = 0; i <= n; i++)
{
printf("%d: key:%d, value:%d\n", i, heap[i].key, heap[i].value);
}
for (int i = 0; i <= n; i++)
{
printf("%d --> %d\n", i, heapIndex[i]);
}
}
bool ifHashLevel(int l)
{
for (int i = 0; i < numHLevel; i++)
{
if (hashLevel[i] == l)
{
return true;
}
}
hashLevel[numHLevel] = l;
numHLevel++;
return false;
}
int main()
{
//freopen("1062.in", "r", stdin);
//freopen("1062.out", "w", stdout);
scanf("%d%d", &m, &n);
memset(hashLevel, 0, sizeof(hashLevel));
numHLevel = 0;
memset(level, 0, sizeof(level));
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
map[i][j] = MAX_INT;
}
}
for (int i = 0; i <= n; i++)
{
map[i][i] = 0;
}
int itemPrice = 0;
int itemMaster = 0;
int numOfRelatedItems = 0;
scanf("%d%d%d", &itemPrice, &itemMaster, &numOfRelatedItems);
map[0][n] = itemPrice; //我建的图是0为起始节点,n为虚拟的终止节点从0-->n
level[0] = itemMaster;
int minMaster = itemMaster - m;
int maxMaster = itemMaster + m;
for (int i = 0; i < numOfRelatedItems; i++)
{
int tmp;
scanf("%d", &tmp);
tmp--;
scanf("%d", &map[0][tmp]);
}
for (int i = 1; i < n; i++)
{
scanf("%d%d%d", &itemPrice, &itemMaster, &numOfRelatedItems);
//不能和国王交易的节点直接舍弃
if (itemMaster <= maxMaster && itemMaster >= minMaster)
{
map[i][n] = itemPrice;
}
level[i] = itemMaster;
for (int j = 0; j < numOfRelatedItems; j++)
{
if (itemMaster > maxMaster || itemMaster < minMaster)
{
int tmp;
scanf("%d", &tmp);
scanf("%d", &tmp);
}
else
{
int tmp;
scanf("%d", &tmp);
tmp--;
scanf("%d", &map[i][tmp]);
}
}
}
//穷举交易中最小的级别,用hashLevel数组优化,保证穷举不重复
int ans = 2147483640;
for (int Leveli = 0; Leveli < n; Leveli++)
{
int minLevel = level[Leveli];
int maxLevel = minLevel + m;
if (ifHashLevel(minLevel) || minLevel > maxMaster || minLevel < minMaster)
{
break;
}
memset(dis, 0, sizeof(dis));
for (int i = 0; i <= n; i++)
{
dis[i] = map[0][i];
heap[i].value = dis[i];
heap[i].key = i;
heapIndex[i] = i;
}
heapSize = n + 1;
buildHeap();
//print();
for (int i = 0; i <= n; i++)
{
node k = getHeapHead();
//printf("\n\nNO.%d:\nhead: %d\n", i, k.key);
//print();
//printf("\n");
if (k.key == n)
{
break;
}
if (level[k.key]<minLevel || level[k.key]>maxLevel)
{
continue;
}
for (int j = 0; j <= n; j++)
{
if (dis[j] > dis[k.key] + map[k.key][j])
{
dis[j] = dis[k.key] + map[k.key][j];
heap[heapIndex[j]].value = dis[j];
upAdjHeap(heapIndex[j]);
}
}
//print();
}
if (ans > dis[n])
{
ans = dis[n];
}
}
printf("%d\n", ans);
return 0;
}