poj1062 昂贵的聘礼

 做这题代价确实很昂贵,从昨天晚上一直到今天上午都在debug,今天上午提交还出现各种WA。。。比较明显的最短路,有几个地方要注意一下,首先建图有个地方要注意以下,这题是用临界矩阵存储的有向图,而且是由交换品指向购买品,然后将虚节点设为购买品的价值,最后枚举每一个可能地位区间di求最短路,因为对于区间

[check[i]-di, di+check[1]]可能会相距2*di个地位差,这明显不符合题意,所以需要枚举每一个地位区间,此题用SPFA0ms,dij16ms

 

#include <iostream>
#include <string.h>
using namespace std;
const int eps = 1000000;
const int size = 300;
int maze[size][size];
int n, m;
int dist[size];
int que[100*size];
bool visited[size];
int check[size];
int di;
void SPFA(int s, int ed)
{
     memset(visited, false, sizeof(visited));
     for (int i = 1; i <= n+di; i ++){
         dist[i] = eps;
         for (int j = 1; j <= n+di; j ++){
             if (!maze[i][j] && i != j){
                maze[i][j] = eps;               
             }
         }   
     }
     int rear, front;
     rear = 1, front = 0;
     que[front] = s;
     dist[s] = 0;
     visited[s] = true;
     while (front < rear){
           int u = que[front ++];
           visited[u] = false;
           for (int i = 0; i <= n; i ++){
               if ( (check[i]>=ed && check[i]<=ed+di) && dist[i] > dist[u]+maze[u][i]){
                  dist[i] = dist[u] + maze[u][i];
                  if (!visited[i]){
                     que[rear ++] = i;
                     visited[i] = true;
                  }   
               }
           }
     }
}
void dij(int v, int ed)
{
 int i,j,ff,min;
  for (int i = 1; i <= n+di; i ++){
         dist[i] = eps;
         for (int j = 1; j <= n+di; j ++){
             if (!maze[i][j] && i != j){
                maze[i][j] = eps;               
             }
         }   
     }
 for (i = 0; i <= n; i ++){
        if ((check[i] >= ed && check[i] <= ed+di))
     dist[i] = maze[0][i];
     visited[i] = false;
 }
 visited[0] = true;
 ff = 0;
 while (1){
  min=INT_MAX;
  for(j = 0; j <= n; j ++){
   if(!visited[j]){
    if(dist[j] < min && (check[j] >= ed && check[j] <= ed+di)){
     min = dist[j];
     ff = j;
    }
   }
  }
  visited[ff] = true;
  if (ff == 1)break;
  for(j = 0;j <= n; j ++){
   if(!visited[j] && (min+maze[ff][j] < dist[j]) && (check[j] >= ed && check[j] <= ed+di)){
    dist[j] = min+maze[ff][j];
   }
  }
 }
}

int main()
{
   
    while (scanf("%d%d", &di, &n) != EOF){
          memset(check, 0, sizeof(check));
          int num = -1;
          for (int i = 1; i <= n; i ++){
              int c;
                scanf("%d%d%d", &maze[0][i], &check[i], &c);
                while (c --){
                      int num1, money;
                      scanf("%d%d", &num1, &money);
                      if (maze[num1][i] < money || !maze[num1][i]){
                         maze[num1][i] = money;            
                      }
                }
          }
          int minn = INT_MAX;
          for (int i = check[1]-di; i<= check[1]; i ++){
              SPFA(0, i);
              //dij(0, i);
              if (minn > dist[1]){
                 minn = dist[1];
              }
          }
         printf("%d\n", minn);
    }
    return 0;   
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值