hdu3440 差分约束系统

来源:互联网 发布:视频人脸打马赛克软件 编辑:程序博客网 时间:2024/05/21 08:03

解题报告

题目 http://acm.hdu.edu.cn/showproblem.php?pid=3440

算法 :差分约束系统

思路:读懂题后想了很久,最后想到的是二分加判定,但是如何判定却不会,后来才知道这是道差分约束系统的题,(听说官方解题报告是极其诡异的贪心,没有看到)。有了差分约束这个念头,就不难再去思考此题了。差分约束系统解决的是一组不等式的解,对于此题,不等式还是比较好写的,

1. 位置相邻的两个house间距>= 1<id, id - 1,-1>(2=< id <=N)

2. 高度相邻的两个house间距 <= D<min(f[i-1].id, f[i].id),max(f[i-1].id, f[i].id), D>(2 <= i<= N)

因为是求在大值,因此用最短路,要注意的是最短路的起始点和终止点要跟与最低点和最高点的相对位置而定,要保证从左往右(因为建图的坐标位置就是从左往右的)。也就是令dis[min(minh,maxh)] = 0, 输出dis[max(minh,maxh)]即可,由于图肯定是联通的,应此不用多加源点。

由于maxn×D = 1 × 10^9, 因此初始值INF一定要很大,悲剧的检查了一上午,最后发现是这个问题,悔死我了!INF = 0x3fffffff就差不多了.214000000都不行。。。。。。

 

提交情况 wrong answer N INF值偏小(210000000))

收获与经验 :检查程序问题是一定要全面,不能只看主要的函数功能部分。看清楚数据范围。对差分约束系统函数不是很熟,需要再做题。

ACcode

//代码中最短路径分别用了SPFAbellman

#include <stdio.h>

#include <algorithm>

 

using namespacestd;

#define MAXN 1010

#define INF 0x3fffffff

#define MIN(a, b) ((a) < (b) ? (a) :(b))

#define MAX(a, b) ((a) > (b) ? (a) :(b))

 

struct NODE{

   int st, to, len, next;

};

NODE edges[MAXN * 100];

inthead[MAXN], ad;

 

struct NOde{

   int high, xu;

} tall[MAXN];

intdis[MAXN], queue[MAXN], in[MAXN],times[MAXN];

int n, D;

 

bool comp(const NOde A,const NOde B){

   return A.high <B.high;

}

voidclear(){

   memset(head, -1, sizeof(head));

   ad = 0;

}

void insert(int u,int v, int d){

   edges[ad].st = u; edges[ad].to = v; edges[ad].len = d;edges[ad].next = head[u]; head[u] = ad ++;

}

void built(int s,int t){

   clear();

   for(int i = 1; i < n; i++){

      insert(i, i - 1, -1);

      insert(MIN(tall[i].xu, tall[i - 1].xu), MAX(tall[i].xu, tall[i -1].xu), D);

   }

}

int SPFA(int rS,int rT){

   int front = 0, tail = 0, i, u, v,p;

   memset(in, 0 , sizeof(in));

   memset(times, 0, sizeof(times));

   for(i = 0; i < n; i++) dis[i] = INF;

   queue[tail++] = rS;

   dis[rS] = 0;

   in[rS] = 1;

   times[rS] ++;

   while(front != tail){

      u = queue[front];

      front = (front + 1) % MAXN;

      in[u] = 0;

      for(p = head[u]; ~p; p =edges[p].next){

          v = edges[p].to;

          if(dis[v] > dis[u] +edges[p].len){

             dis[v] = dis[u] + edges[p].len;

             if(!in[v]){

                 queue[tail] = v;

                 tail = (tail + 1) % MAXN;

                 in[v] = 1;

                 times[v] ++;

                 if(times[v] > n)return -1;

             }

          }

      }

   }

   return dis[rT];

}

intbellman(int er,int et){

   int i, j;

   for(i = 0; i < n; i++) dis[i] = INF;

   dis[er] = 0;

   for(i = 0; i < n; i++){

      for(j = 0; j < ad; j++)

          if(dis[edges[j].st]< INF &&dis[edges[j].to] > dis[edges[j].st] +edges[j].len)

             dis[edges[j].to] = dis[edges[j].st] + edges[j].len;

   }

   for(j = 0; j < ad; j++)

      if(dis[edges[j].to]> dis[edges[j].st] + edges[j].len) return -1;

   return dis[et];

}

int main(){

   int CASE, T, i, s, t;

   scanf("%d",&CASE);

   for(T = 1; T <=CASE; T ++){

      scanf("%d %d",&n, &D);

      s = t = 0;

      for(i = 0; i < n; i++){

          scanf("%d",&tall[i].high);

          tall[i].xu = i;

      }

      sort(tall, tall + n, comp);

      s = tall[0].xu;

      t = tall[n - 1].xu;

      built(s, t);

      int ans = SPFA(MIN(s, t), MAX(s,t));

      //int ans = bellman(MIN(s, t), MAX(s,t));

      printf("Case %d: %d\n", T,ans);

   }

   return 0;

}

原创粉丝点击