题解 P2296 【寻找道路】

· · 题解

分别顺序 逆序 储存边 先逆向跑一边 找出能到的点 再跑一边SPFA 先跑一边 我统计从终点出发的点 被访问过几次 被访问的次数等于出边数 就是合法的 签到题

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
vector<int>p[10010];//ni
int ru[10010]={0};
int chu[10010]={0};
bool map[10010];
bool vis[10010];
int n,m;
int s,t;
queue<int>q;
queue<int>Q;
int dis[10010];
int ans[10010];
vector<int>P[10010];//shun
void bfs(int x)
{
    while(!Q.empty())
    {
        int tmp=Q.front();
        Q.pop();
        int l=p[tmp].size();
        for(int i=0;i<l;i++)
        {
            int temp=p[tmp][i];
            if(i==1)
            {
            }
            ans[temp]++;
            if(vis[temp])
            {
                Q.push(temp);
                vis[temp]=false;
            }
        }
    }
}
void spfa(int x)
{
    while(!q.empty())
    {
        int tmp=q.front();
        q.pop();
        int t=P[tmp].size();
        for(int i=0;i<t;i++)
        {
            int temp=P[tmp][i];
            if(map[temp]&&vis[temp])
            {
                if(dis[temp]>dis[tmp]+1)
                {
                    dis[temp]=dis[tmp]+1;
                    q.push(temp);
                    vis[temp]=false;
                }
            }
        }
        vis[tmp]=true;
    }
}
int main()
{
    memset(dis,127,sizeof(dis));
    memset(vis,true,sizeof(vis));
    memset(map,false,sizeof(map));
    memset(ans,0,sizeof(ans));
    memset(chu,0,sizeof(chu));
    memset(ru,0,sizeof(ru));
    int x,y;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        map[i]=true;
    }
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        if(x!=y)
        {
        P[x].push_back(y);
        p[y].push_back(x);
        chu[x]++;
        ru[y]++;
    }
    }
    cin>>s>>t;
    map[t]=true;
    Q.push(t);
    bfs(t);
    for(int i=1;i<=n;i++)
    {
        if(ans[i]==chu[i]&&chu[i]!=0)
        {
            map[i]=true;
        }
        else
        {
            map[i]=false;
        }
    }
   map[t]=true;
    memset(vis,true,sizeof(vis));
    dis[s]=0;
    q.push(s);
    spfa(s);
    if(dis[t]>99999)
    {
        cout<<"-1";
    }
    else
    {
        cout<<dis[t];
    }
    return 0;
}