[NOIP 2014] 寻找道路

[题目链接]

          http://uoj.ac/problem/19

[算法]

        首先,在反向图上从终点广搜,求出每个点是否可以在答案路径中

        然后在正向图中求出源点至终点的最短路,同样可以使用广搜

        时间复杂度 : O(N)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10010
#define MAXM 200010

struct edge
{
        int to,nxt;
} e[MAXM << 1];

int i,n,m,u,v,s,t,tot;
int head[MAXN],rhead[MAXN],deg[MAXN];
bool flag[MAXN];

namespace IO
{
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar())
        {
            if (c == '-') f = -f;
        }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    template <typename T> inline void write(T x)
    {
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
    template <typename T> inline void writeln(T x)
    {
        write(x);
        puts("");
    }
} ;
inline void addedge(int u,int v)
{
        tot++;
        e[tot] = (edge){v,head[u]};
        head[u] = tot;
}
inline void addredge(int u,int v)
{
        tot++;
        e[tot] = (edge){v,rhead[u]};
        rhead[u] = tot;
}
inline void bfs1(int s)
{
        int i,u,v,l,r;
        static int q[MAXN],cnt[MAXN];
        static bool visited[MAXN];
        for (i = 1; i <= n; i++) cnt[i] = 0;
        q[l = r = 1] = s;
        flag[s] = true;
        while (l <= r)
        {
                u = q[l];
                l++;
                for (i = rhead[u]; i; i = e[i].nxt)
                {
                        v = e[i].to;
                        if (!visited[v])
                        {
                                visited[v] = true;
                                q[++r] = v;
                        }
                        cnt[v]++;
                }
        }    
        for (i = 1; i <= n; i++) flag[i] = (cnt[i] == deg[i]);
}
inline int bfs2(int s)
{
        int i,u,v,l,r;
        static int q[MAXN],dist[MAXN];
        static bool visited[MAXN];
        if (!flag[s]) return -1;
        for (i = 1; i <= n; i++) visited[i] = false;
        q[l = r = 1] = s;
        dist[s] = 0;
        visited[s] = true;
        while (l <= r)
        {
                u = q[l];
                l++;
                for (i = head[u]; i; i = e[i].nxt)
                {
                        v = e[i].to;
                        if (!visited[v] && flag[v])
                        {
                                visited[v] = true;
                                dist[v] = dist[u] + 1;
                                q[++r] = v;
                        }
                }
        }
        return dist[t] > 0 ? dist[t] : -1;
}

int main() 
{
        
        IO :: read(n); IO :: read(m);
        for (i = 1; i <= m; i++)
        {
                IO :: read(u); IO :: read(v); 
                addedge(u,v);
                addredge(v,u);    
                deg[u]++;
        }
        IO :: read(s); IO :: read(t);
        bfs1(t);
        IO :: writeln(bfs2(s));
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9463834.html