Nowcoder contest 370B Rinne Loves Graph 【分層圖最短路】
阿新 • • 發佈:2019-03-12
typedef spa head 下一個 bsp 分析 continue edge org
<題目鏈接>
題目大意:
Island 是有一些奇怪的城鎮和道路構成的(題目需要,遊戲黨勿噴),有些城鎮之間用雙向道路連接起來了,且每條道路有它自己的距離。但是有一些城鎮已經被派兵戒嚴,雖然主角可以逆天改命強闖,但是為了體驗該遊戲的平衡性,他們只能穿過不超過 K 次被戒嚴的城鎮。 定義“穿過”:從一個戒嚴的點出發到達任意一個點,都會使得次數加1 現在他們想從 1 號城鎮最快的走到 n 號城鎮(即出口),現在他們想讓你告訴他們最短需要走多少路。
2≤n≤800,1≤m≤4000,1≤k≤10,1≤w≤10^6
解題分析:
本題很明顯是一道分成圖最短路的題主要的就是怎麽處理"穿過"K個點,我是通過在最短路松弛過程中,判斷下一個點是否是封鎖點,是的話,就要利用分層圖的性質進行松弛。因為題目規定的是穿過k個封鎖點,所以我們需要對起點和終點進行處理。如果起點是封鎖點,那麽k--,如果終點是封鎖點k++,因為起點是一定要穿過的,而終點穿不過。
#include <bits/stdc++.h> using namespace std; #define clr(a,b) memset(a,b,sizeof(a)) #define rep(i,s,t) for(int i=s;i<=t;i++) typedeflong long ll; const int N = 805, M = 4005; int n,m,k,cnt; int isgo[N],head[N]; template<typename T> inline void read(T&x){ x=0;int f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar(); } while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} x*=f; } struct Edge{ int to,nxt;ll w; }edge[M<<1]; struct Node{ int loc,lev;ll dist; Node(int _loc=0,int _lev=0,ll _dist=0):loc(_loc),lev(_lev),dist(_dist){} bool operator < (const Node &tmp)const{ return dist>tmp.dist; } }node[N][15]; int vis[N][15]; inline void init(){ cnt=0;clr(head,-1); } inline void add(int u,int v,ll w){ edge[++cnt].to=v,edge[cnt].nxt=head[u]; edge[cnt].w=w;head[u]=cnt; } void Dij(){ rep(i,1,n) rep(j,0,k){ node[i][j].loc=i,node[i][j].lev=j; node[i][j].dist=1e18;vis[i][j]=0; } priority_queue<Node>q; node[1][0].dist=0; q.push(node[1][0]); while(!q.empty()){ Node now=q.top();q.pop(); int loc=now.loc,lev=now.lev; if(vis[loc][lev])continue; vis[loc][lev]=1; for(int i=head[loc];~i;i=edge[i].nxt){ int v=edge[i].to;ll cost=edge[i].w; if(!isgo[v] && node[v][lev].dist>node[loc][lev].dist+cost){ //進行同層次建進行正常的松弛 node[v][lev].dist=node[loc][lev].dist+cost; q.push(Node(v,lev,node[v][lev].dist)); } if(isgo[v] && (lev+1)<=k && node[v][lev+1].dist>node[loc][lev].dist+cost){ //不是封鎖點的就沒有必要利用分層圖進行松弛,因為在正常的一層就已經松弛了 node[v][lev+1].dist=node[loc][lev].dist+cost; q.push(Node(v,lev+1,node[v][lev].dist)); } } } } int main(){ init(); read(n);read(m);read(k); rep(i,1,n) read(isgo[i]); rep(i,1,m){ int u,v;ll w;read(u);read(v);read(w); add(u,v,w);add(v,u,w); } if(isgo[1])k--; if(isgo[n])k++; Dij(); ll ans=1e18;rep(i,0,k)ans=min(ans,node[n][i].dist); printf("%lld\n",ans); }
Nowcoder contest 370B Rinne Loves Graph 【分層圖最短路】