版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/81877629
/**
HDU 6386 Age of Moyu DFS+BFS
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6386
题意:1-->n的最小换乘次数
分析:前向星双向建图 对于每个节点多记录一个nxt和pre(父亲和儿子)
bfs 内 queue内存放的是到当前节点 和当前节点的最小交换次数
d[v] 存放是是1-->v的最小交换次数 也算是小优化吧
对于每一个节点 跑一发dfs d[v]>所有到达该点的交换次数sum进行不断的更新
反过来想 如果说这个点的所有可连通的点已经遍历 可直接利用并查集思想进行路径压缩;
对于当前大于的情况且存在连通 可以直接对当前节点进行删边的操作了 直接将nxt-->-1
由于删边的路径压缩的缘故使得dfs可行化
*************tricks**********
read视情况喷出题人..... scanf
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
/**********************************************Head-----Template****************************************/
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){ll gg=gcd(a,b);a/=gg;if(a<=LLONG_MAX/b) return a*b;return LLONG_MAX;}
/********************************Head----Temlate**********************************************/
const int INF=0x3f3f3f3f;
const int maxn=1e5+5;
int n, m;
struct Edge {
int v,w,pre,nxt;
}E[maxn*4];
int head[maxn],tot;
int sum,d[maxn];
void init(int n) {
for(int i=1;i<=n;i++) head[i]=-1, d[i]=INF;
tot=0;
}
void edge_add(int u, int v, int w) {
E[tot]=(Edge){ v,w,-1,head[u]};
if(E[tot].nxt!=-1) E[E[tot].nxt].pre=tot;
head[u]=tot++;
}
typedef pair<int,int>pii;
int pre, nxt;
queue<pii>q;
void dfs(int u, int c) {
int v,w;
for(int i=head[u];~i;i=E[i].nxt){
v=E[i].v,w=E[i].w;
if(w!=c&&c!=-1) continue;
if(d[v]>sum){
if(~E[i].pre){
E[E[i].pre].nxt=E[i].nxt;
if(~E[i].nxt) E[E[i].nxt].pre=E[i].pre;//路径压缩
}
else {
head[u]=E[i].nxt;
if(~E[i].nxt) E[E[i].nxt].pre=-1;//删边操作;
}
q.push(pii(v,sum+1));
d[v]=sum+1;
dfs(v,w);
}
}
}
int bfs() {
while(!q.empty()) q.pop();
q.push(pii(1, 0));
d[1]=0;
while(!q.empty()){
pii now=q.front();q.pop();
sum=now.second;
if(now.first==n) return now.second;
dfs(now.first,-1);
}
return -1;
}
int x,y,z;
int main() {
while(scanf("%d %d",&n,&m)!=EOF) {
init(n);
for(int i=1;i<=m;i++) {
//read(x),read(y),read(z);
scanf("%d %d %d",&x,&y,&z);
edge_add(x,y,z );
edge_add(y,x,z);
}
int ans=bfs();
printf("%d\n",ans);
}
return 0;
}