LGOJ P2296 寻找道路

Posted #include

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LGOJ P2296 寻找道路相关的知识,希望对你有一定的参考价值。

思路比较直接:

1° 建反图,从\(t\)开始\(dfs\),以得到所有能到达到\(t\)的点,用\(rc[]\)数组记录。\(rc[u]==1\)表示\(u\)能直接或间接到达\(t\)

//vector<int> RG[N];表示反图
void dfs(int u)
{
    rc[u]=1;
    for(int i=0;i<RG[u].size();i++)
    {
        int v=RG[u][i];
        if(rc[v]==0)dfs(v);
    }
}
                                   

2° 探究每一个点\(u\)是否能被选择(能否参与构成路径),用\(sel[]\)数组记录。\(sel[u]==1\)表示\(u\)是可以出现在路径上的点。枚举\(u\)的出边,求\(sel[u]\):
\[ sel[u]=rc[v_1] \& rc[v_2] \&...\&rc[v_{end}]. \]
其中,\(v_1,v_2,...v_{end}\)\(u\)的出边直连的点;\(\&\)是逻辑与运算符;

//vector<int> G[N];表示原图
for(int u=1;u<=n;u++)
{
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        sel[u]&=rc[v];
    }
}

3° 对于所有\(sel[vertex]==1\)的点,跑\(Dijkstra\)模板。

完整代码:

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
    char c=getchar();int x=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x;
}
const int N=10005,M=200005,INF=0x3f3f3f3f;
bool rc[N],GG[N][N],sel[N];
int d[N];
int n,m,s,t;
vector<int> G[N];
vector<int> RG[N];
bool vis[N];
priority_queue< pair<int,int> >Q;

void dfs(int u)
{
    rc[u]=1;
    for(int i=0;i<RG[u].size();i++)
    {
        int v=RG[u][i];
        if(rc[v]==0)dfs(v);
    }
}

void dijk()
{
    for(int i=1;i<=n;i++)d[i]=INF;
    memset(vis,0,sizeof(vis));
    d[s]=0;
    Q.push(make_pair(0,s));
    if(sel[s]==0)return;
    while(!Q.empty())
    {
        int u=Q.top().second;
        Q.pop();
        if(vis[u])continue;
        vis[u]=1;
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(sel[v]&&d[v]>d[u]+1)
            {
                d[v]=d[u]+1;
                Q.push(make_pair(-d[v],v));
            }
        }
    }
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u=read();
        int v=read();
        if(u==v)continue;
        if(GG[u][v])continue;
        GG[u][v]=1;
        G[u].push_back(v);
        RG[v].push_back(u);
    }
    cin>>s>>t;
    dfs(t);
    for(int i=1;i<=n;i++)sel[i]=1;
    for(int u=1;u<=n;u++)
    {
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            sel[u]&=rc[v];
        }
    }
    dijk(); 
    if(d[t]!=INF)cout<<d[t];
    else cout<<"-1";
    return 0;
}

以上是关于LGOJ P2296 寻找道路的主要内容,如果未能解决你的问题,请参考以下文章

P2296 寻找道路

P2296 寻找道路

洛谷——P2296 寻找道路

P2296 寻找道路

洛谷P2296寻找道路

洛谷 [P2296] 寻找道路