HDU 5361(dijkstra变形)

来源:互联网 发布:数据的保密性 编辑:程序博客网 时间:2024/04/25 05:10

本题目直接套用dijkstra算法会超时的,因为每个点被更新的次数可能很多、

那么dijkstra算法的核心是,去没有加入到(已经求得最短路的集合)外,d值最小的加入集合,并松弛连边,

(证明 : 集合外权值最小的点,一定存在一条最短路,那么取这条最短上在集合外的第一个点v,那么这个点已经达到最优值,d[v] = best[ v] <= best[ u ]<=d[u] ,又v,u同在集合外面,d[ u] <=d[ v ],要是两个不等式成立,那么u已经达到最优值。)

对于本题目,有个特殊性,即从一点出发,到左右两个集合所有点的权值相同,那么只需要没把一个求得best的点加入集合时,加入node(best[ u ] + cost [u ] , id),按第一维排序,

那么取出的第一个node,node.id 到达的所有点都将达到最优路径值,其值为该node的第一维值。那么这样把所有到达的点同操作加入,即每个点只进入集合一次。nlog(n)

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <map>#include <cmath>#include <cctype>#include <set>#define ls rt<<1#define rs rt<<1|1#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define clr(a,x) memset(a,x,sizeof(a))#define rep1(i,x,y) for(int i=x;i<=y;i++)#define rep(i,n) for(int i=0;i<(int)n;i++)using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;const ll oo = 0x3f3f3f3f3f3f3f;const int N = 2*1e5+1000;set<int> vis;struct node{   ll dis;   int id;   node(){}   node(ll dis,int id):dis(dis),id(id){}   bool operator<(const node& rhs)const{      if(dis!=rhs.dis) return dis<rhs.dis;      return id<rhs.id;   }};set<node> Q;int l[N],r[N],n;ll c[N],d[N];int main(){    int T;    scanf("%d",&T);    while(T--){       scanf("%d",&n);       rep(i,n) scanf("%d",&l[i]);       rep(i,n) scanf("%d",&r[i]);       rep(i,n) scanf("%I64d",&c[i]);       vis.clear();       rep1(i,1,n-1) vis.insert(i);       memset(d,-1,sizeof(d));       d[0]=0; Q.clear();       Q.insert(node(c[0],0));       while(!Q.empty()){            node u = *Q.begin();            Q.erase(Q.begin());            rep(i,2){               int L,R;               if(!i) L=u.id-r[u.id],R=u.id-l[u.id];               else L=u.id+l[u.id],R=u.id+r[u.id];               set<int>::iterator it = vis.lower_bound(L),it2;               while(it !=vis.end() && (*it)<=R){                    int v = *it;                    d[v] = u.dis;                    Q.insert(node(u.dis+c[v],v));                    vis.erase(it++);               }            }       }       rep(i,n){           if(i) printf(" ");           printf("%I64d",d[i]);       }  printf("\n");    }    return 0;}




0 0
原创粉丝点击