[题解]CF625 D

思路:从终点反向bfs,求出每个点到终点的距离

然后枚举原图的每一条边,计算出度

最后对于路径上每个点判断即可

code


#include<bits/stdc++.h>
namespace my_std
{
    using namespace std;
    #define rep(i,a,b) for (int i=(a);i<=(b);i++)
    #define drep(i,a,b) for (int i=(a);i>=(b);i--)
    #define go(u) for (int i=head[(u)];i;i=e[i].nxt)
    #define pf printf
    #define writeln(x) write(x),putchar('\n')
    #define writesp(x) write(x),putchar(' ')
    #define mem(x,v) memset(x,v,sizeof(x))
    typedef long long ll;
    const int INF=0x7fffffff;
    inline int read()
    {
        int sum=0,f=1;
        char c=0;
        while (!isdigit(c))
        {
            if (c=='-') f=-1;
            c=getchar();
        }
        while (isdigit(c))
        {
            sum=(sum<<1)+(sum<<3)+(c^48);
            c=getchar();
        }
        return sum*f;
    }
    void write(int k)
    {
        if (k<0) putchar('-'),k=-k;
        if (k>=10) write(k/10);
        putchar(k%10+'0');
    }
}
using namespace my_std;
const int N=200010;
int n,m,head[N],HEAD[N];
int s,t,cnt1,cnt2;
int dis[N],p[N],out[N];
int maxx=0,minn=0;
struct edge
{
    int to,nxt;
}e[N<<1],E[N<<1];
void add1(int u,int v)
{
    e[++cnt1].to=v;
    e[cnt1].nxt=head[u];
    head[u]=cnt1;
}
void add2(int u,int v)
{
    E[++cnt2].to=v;
    E[cnt2].nxt=HEAD[u];
    HEAD[u]=cnt2;
}
void bfs(int f)
{
    queue<int>q;
    dis[f]=1;
    q.push(f);
    while (!q.empty())
    {
        int u=q.front();
        for (int i=HEAD[u];i;i=E[i].nxt)
        {
            int v=E[i].to;
            if (dis[v]==0)
            {
                dis[v]=dis[u]+1;
                q.push(v);
            }
        }
        q.pop();
    }
}
int main()
{
    n=read(),m=read();
    int u,v;
    rep(i,1,m)
    {
        u=read(),v=read();
        add1(u,v),add2(v,u);
    }
    int size=read();
    rep(i,1,size) p[i]=read();
    bfs(p[size]);
    rep(u,1,n) go(u)
    {
        int v=e[i].to;
        if (dis[v]+1==dis[u])
        {
            out[u]++;
        }
    }
    rep(i,1,size-1)
    {
        if (dis[p[i]]!=dis[p[i+1]]+1) minn++,maxx++;
        else if (dis[p[i]]==dis[p[i+1]]+1&&out[p[i]]>=2) maxx++;
    }
    writesp(minn),writeln(maxx);
}

猜你喜欢

转载自www.cnblogs.com/ZHANG-SHENG-HAO/p/12416714.html