HDU

原题链接HDU - 6386

题意: 

给你n个站点,m条边连接。每一条边都有一个编号,顺着编号相同的一直走整条路上只花费为1。如果在中途换到不同编号的边,则花费会增加。

思路

或许一开始会想到最短路,我们先建个图然后用dijkstra跑一下。建图的话我们可能想到dfs或者bfs去搜索,相同编号则花费为1。然后....我们就TLE了

关于TLE主要是建图上我们单纯dfs或者bfs去搜索建图把新图中所有边权值求出来很费时间。 我们可以换一个思路,从最简单的搜索思路开始。

比如迷宫问题,我们一般可以用bfs找到最短的路径。 对于一个很长的路, a - c - d - e (走了四次,但是由于编号相同费用只花了1,那么我们可以用dfs来压缩一下路径。即我们dfs到 e了,说明 a-e 路径被压到了1。 所以我们在边bfs 边用 dfs压缩路径,最后就将其变为了最简单的迷宫最短路径问题。

code:

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
const int maxn = 1e5+5;
int dist[maxn];
int head[maxn];
int vis[maxn];
int top;
int n,m;

struct Edge
{
    int v,vis,next;
    int color;
}edge[maxn<<2];
queue<int>Q;
void add(int u,int v,int color)
{
    edge[top].v = v;
    edge[top].next = head[u];
    edge[top].color = color;
    edge[top].vis = 0;
    head[u] = top++;

    edge[top].v = u;
    edge[top].next = head[v];
    edge[top].color = color;
    edge[top].vis = 0;
    head[v] = top++;
}
void dfs(int u,int color,int dis)
{
    if(!vis[u])
    {
        vis[u] = 1;
        dist[u] = dis;
        if(u==n) return;
        Q.push(u);
    }
    
    for(int i=head[u]; ~i ; i = edge[i].next)
    {
        if(edge[i].vis) continue;
        if(edge[i].color == color)
        {
            edge[i].vis = 1;
            dfs(edge[i].v,color,dis);
        }
        
    }
    
}
void bfs(int s)
{
    memset(vis,0,sizeof(vis));
    dist[s] = 0;
    dist[n] = -1;
    vis[s] = 1;
    while(!Q.empty()) Q.pop();
    Q.push(s);
    while(!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        for(int i=head[u]; ~i ; i = edge[i].next)
        {
            if(edge[i].vis) continue;
            edge[i].vis = 1;
            dfs(edge[i].v,edge[i].color,dist[u]+1);
            if(dist[n]>0) return;
            
        }
    }
    return ;
}
void init()
{

    memset(dist,0,sizeof(dist));
    memset(head,-1,sizeof(head));
    top = 0;
}
int main()
{
    IOS
    while(cin>>n>>m)
    {
        init();
        if(!m)
        {
            printf("-1
"); 
            continue;
        }
        
        for(int i=0;i<m;i++)
        {
            int u,v,color;
            cin>>u>>v>>color;
            add(u,v,color);
        }
        bfs(1);
        printf("%d
",dist[n]);
    
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Tianwell/p/11377969.html