1. 程式人生 > >HDU - 6386 Age of Moyu 2018 Multi-University Training Contest 7 (Dijkstra變型)

HDU - 6386 Age of Moyu 2018 Multi-University Training Contest 7 (Dijkstra變型)

pri == continue 不同 def ear color using find

題意:N個點M條邊的無向圖,每條邊都有屬於自己的編號,如果一條路徑上的邊編號都相同,那麽花費僅為1;改變至不同編號的路徑,花費加1,無論這個編號之前是否走過。

分析:記錄每個點的最小花費,再用set維護這個最小花費對應的前驅邊的編號,可能有多個不同的前驅編號。如果當前狀態可以更新點最小花費,那麽將set清空並加入前驅編號;如果與最小花費相等且前驅的編號不在集合中,那麽將前驅的狀態加入集合中。

*BFS要用優先隊列,否則會錯。

#include<bits/stdc++.h>
using namespace std;
const int maxn =1e5+5;
const int INF = 0x3f3f3f3f
; struct Edge{ int v,id,next; }edges[maxn<<2]; int head[maxn],tot; int d[maxn]; set<int> sta[maxn]; void init() { tot=0; memset(head,-1,sizeof(head)); } void AddEdge(int u,int v,int id) { edges[tot] = (Edge){v,id,head[u]}; head[u] = tot++; } struct Node{ int
val,u; int pre,fa; bool operator <(const Node &p) const{return val>p.val;} }; void BFS(int s,int t) { memset(d,INF,sizeof(d)); d[s] = 0; priority_queue<Node> Q; Q.push((Node){d[s],s,-1,-1}); while(!Q.empty()){ Node x= Q.top();Q.pop(); int pre = x.pre, u = x.u;
if(x.val> d[u]) continue; else if(x.val==d[u]){ bool tag = true; if(sta[u].find(pre)!=sta[u].end()) continue; sta[u].insert(pre); } else{ d[u] = x.val; sta[u].clear(); sta[u].insert(pre); } for(int i=head[u];~i;i=edges[i].next){ int v = edges[i].v,now = edges[i].id; if(v==x.fa) continue; //反向邊 if((d[u]+(pre!=now))<=d[v]){ d[v] = d[u] + (pre!=now); if(v!=t) Q.push((Node){d[v],v,now,x.u}); } } } } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int N,M; int u,v,id; while(scanf("%d%d",&N,&M)==2){ for(int i=1;i<=N;++i) sta[i].clear(); init(); while(M--){ scanf("%d%d%d",&u,&v,&id); AddEdge(u,v,id); AddEdge(v,u,id); } BFS(1,N); if(d[N]==INF) d[N]=-1; printf("%d\n",d[N]); } return 0; }

HDU - 6386 Age of Moyu 2018 Multi-University Training Contest 7 (Dijkstra變型)