HDU 6386 Age of Moyu DFS+BFS

版权声明:布呗之路的守望者 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;
}

猜你喜欢

转载自blog.csdn.net/hypHuangYanPing/article/details/81877629
今日推荐