zoukankan      html  css  js  c++  java
  • BZOJ1922 [Sdoi2010]大陆争霸[最短路]

    orz极速暴切此题的hkk


    如果没有保护限制,直接跑最短路,现在到达某些点要先经过保护点,那么在跑dijkstra时候每一轮可以先减少这些点保护数量,如果有恰好点没有保护了,说明这个点就可以走了,且这个点$dis$应当是走完所有保护点时间和走到他本身时间的$max$,把他压入堆。这样之后,如果又有其他点可以松弛他,就继续更新$dis$并压入堆。这样可以保证这种点$dis$取出来最小。

    由于这种点入堆的时候其$dis$最小也必须是目前用来松弛的$dis_x$,所以这种点不可能再去松弛已求完最短路的点。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<vector>
     8 #define dbg(x) cerr << #x << " = " << x <<endl
     9 using namespace std;
    10 typedef long long ll;
    11 typedef double db;
    12 typedef pair<ll,int> pii;
    13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    15 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    16 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    17 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    18 template<typename T>inline T read(T&x){
    19     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    20     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    21 }
    22 const int N=3000+7,M=1e5+7;
    23 struct thxorz{int to,nxt,w;}G[M];
    24 vector<int> kekkai[N];
    25 int Head[N],tot,ind[N];
    26 int n,m;
    27 inline void Addedge(int x,int y,int z){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;}
    28 ll dis[N],pre[N];
    29 priority_queue<pii,vector<pii>,greater<pii> > q;
    30 #define y G[j].to
    31 #define z kekkai[x][j]
    32 inline void dij(){
    33     memset(dis,0x3f,sizeof dis);q.push(make_pair(dis[1]=0,1));ll INF=dis[0];
    34     while(!q.empty()){
    35         ll d=q.top().first;int x=q.top().second;q.pop();//dbg(x),dbg(d);
    36         if(d^dis[x])continue;
    37         for(register int j=0;j<kekkai[x].size();++j)if(!(--ind[z])){//dbg(z),dbg(ind[z]);
    38             pre[z]=d;if(dis[z]<INF)q.push(make_pair(dis[z]=_max(dis[z],d),z));//条件判断有无皆可 
    39         }
    40         for(register int j=Head[x];j;j=G[j].nxt)if(MIN(dis[y],_max(d+G[j].w,pre[y])))if(!ind[y])q.push(make_pair(dis[y],y));
    41     }
    42 }
    43 #undef y
    44 #undef z
    45 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    46     read(n),read(m);
    47     for(register int i=1,x,y,z;i<=m;++i)read(x),read(y),read(z),Addedge(x,y,z);
    48     for(register int i=1;i<=n;++i){read(ind[i]);for(register int j=1,x;j<=ind[i];++j)read(x),kekkai[x].push_back(i);}
    49     dij();
    50     printf("%lld
    ",dis[n]);
    51     return 0;
    52 }
    View Code

    总结:有限制条件的最短路除了从重新建图来看,也可以适当更改在dij过程中的步骤,利用dij的贪心原理来进行题目求解。

  • 相关阅读:
    vSphere 6.5支持512e,NVMe SSD呢?
    分布式队列神器 Celery
    www.coursera.org
    各种编码UNICODE、UTF-8、ANSI、ASCII、GB2312、GBK详解
    SSD S.M.A.R.T
    2018世界人工智能大会在上海开幕
    ER TO SQL语句
    E-R图样例
    关于微软的.NET版本系列
    ArcGIS 10.6 安装破解教程
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11597109.html
Copyright © 2011-2022 走看看