zoukankan      html  css  js  c++  java
  • NOIP 2014 寻找道路

    ------------恢复内容开始------------

    洛谷 P2296 寻找道路

    洛谷传送门

    JDOJ 2889: [NOIP2014]寻找道路 D2 T2

    JDOJ传送门

    Description

    在有向图 G中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:

    1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
    2. 在满足条件1的情况下使路径最短。

    注意:图 G中可能存在重边和自环,题目保证终点没有出边。
    请你输出符合条件的路径的长度。

    Input

    第一行有两个用一个空格隔开的整数 n和 m,表示图有 n个点和 m条边。
    接下来的 m行每行 2个整数 x、y,之间用一个空格隔开,表示有一条边从点 x指向点y。最后一行有两个用一个空格隔开的整数 s、t,表示起点为 s,终点为 t。

    Output

    输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出 -1。

    Sample Input

    Input I: 3 2 1 2 2 1 1 3 Input II: 6 6 1 2 1 3 2 6 2 5 4 5 3 4 1 5

    Sample Output

    Output I: -1 Output II: 3

    HINT

    【样例I说明】
    img
    如上图所示,箭头表示有向道路,圆点表示城市。起点 1与终点 3不连通,所以满足题目描述的路径不存在,故输出-1。

    【样例II说明】
    img
    如上图所示,满足条件的路径为 1->3->4->5。注意点 2不能在答案路径中,因为点 2连了一条边到点 6,而点 6不与终点 5连通。

    【数据说明】
    对于 30%的数据,0< n ≤10,0< m ≤20;
    对于 60%的数据,0< n ≤100,0< m ≤2000;
    对于 100%的数据,0< n ≤10,000,0< m ≤200,000,0< x,y,s,t≤n,x≠t。

    Source

    NOIP2014提高组

    题解:

    很容易判断是最短路的题目。终点就是如何判断这个点到底能走还是不能走。解决这个问题的方式也好想,就是反向建图,方法一是反向建图跑最短路,如果节点没被更新就说明不可达。方法二是直接开始搜索,凡是可达的点都可以被搜到。因为反图跑最短路代码不好写(主要是数组名比较复杂),所以考虑直接使用宽搜解决。

    这里还要考虑一个问题,就是题目中所说的“一个点的所有出点都和终点直接或间接相连”,那么宽搜出来的答案,即宽搜得出的与终点相连的点并不全部符合题意,还需要再行删除。建议再开一个标记数组,把宽搜得出的标记数组复制上去,要不然会再更新的时候被更改。

    最后的最短路直接跑SPFA即可。(考场还是建议用DIJ,SPFA随随便便就能被卡)

    代码:

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    int n,m;
    vector<int>v[10005];
    bool cando[10005],er[10005];
    queue<int>q;
    int st,ed;
    int dist[10005];
    void bfs(int ed)
    {
        cando[ed]=1;
        q.push(ed);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0,j=v[x].size();i<j;i++)
                if(!cando[v[x][i]])
                {
                    cando[v[x][i]]=1;
                    q.push(v[x][i]);
                }
        }
    }
    void spfa(int ed)
    {
        q.push(ed);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0,j=v[x].size();i<j;i++)
                if(er[v[x][i]])
                {
                    q.push(v[x][i]);
                    er[v[x][i]]=0;
                    dist[v[x][i]]=dist[x]+1;
                }
        }
    }
    int main()
    {    
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a==b)
                continue;
            v[b].push_back(a);
        }
        scanf("%d%d",&st,&ed);
        bfs(ed);
        memcpy(er,cando,sizeof(cando));
        for(int i=1;i<=n;i++)
            if(!cando[i])
                for(int j=0,k=v[i].size();j<k;j++)
                    if(er[v[i][j]])
                        er[v[i][j]]=0;
        spfa(ed);
        if(dist[st]==0)
        {
            printf("-1");
            return 0;
        }
        else 
        {
            printf("%d",dist[st]);
            return 0;
        }
    }
    

    ------------恢复内容结束------------

    洛谷 P2296 寻找道路

    洛谷传送门

    JDOJ 2889: [NOIP2014]寻找道路 D2 T2

    JDOJ传送门

    Description

    在有向图 G中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:

    1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
    2. 在满足条件1的情况下使路径最短。

    注意:图 G中可能存在重边和自环,题目保证终点没有出边。
    请你输出符合条件的路径的长度。

    Input

    第一行有两个用一个空格隔开的整数 n和 m,表示图有 n个点和 m条边。
    接下来的 m行每行 2个整数 x、y,之间用一个空格隔开,表示有一条边从点 x指向点y。最后一行有两个用一个空格隔开的整数 s、t,表示起点为 s,终点为 t。

    Output

    输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出 -1。

    Sample Input

    Input I: 3 2 1 2 2 1 1 3 Input II: 6 6 1 2 1 3 2 6 2 5 4 5 3 4 1 5

    Sample Output

    Output I: -1 Output II: 3

    HINT

    【样例I说明】
    img
    如上图所示,箭头表示有向道路,圆点表示城市。起点 1与终点 3不连通,所以满足题目描述的路径不存在,故输出-1。

    【样例II说明】
    img
    如上图所示,满足条件的路径为 1->3->4->5。注意点 2不能在答案路径中,因为点 2连了一条边到点 6,而点 6不与终点 5连通。

    【数据说明】
    对于 30%的数据,0< n ≤10,0< m ≤20;
    对于 60%的数据,0< n ≤100,0< m ≤2000;
    对于 100%的数据,0< n ≤10,000,0< m ≤200,000,0< x,y,s,t≤n,x≠t。

    Source

    NOIP2014提高组

    题解:

    很容易判断是最短路的题目。终点就是如何判断这个点到底能走还是不能走。解决这个问题的方式也好想,就是反向建图,方法一是反向建图跑最短路,如果节点没被更新就说明不可达。方法二是直接开始搜索,凡是可达的点都可以被搜到。因为反图跑最短路代码不好写(主要是数组名比较复杂),所以考虑直接使用宽搜解决。

    这里还要考虑一个问题,就是题目中所说的“一个点的所有出点都和终点直接或间接相连”,那么宽搜出来的答案,即宽搜得出的与终点相连的点并不全部符合题意,还需要再行删除。建议再开一个标记数组,把宽搜得出的标记数组复制上去,要不然会再更新的时候被更改。

    最后的最短路直接跑SPFA即可。(考场还是建议用DIJ,SPFA随随便便就能被卡)

    代码:

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    int n,m;
    vector<int>v[10005];
    bool cando[10005],er[10005];
    queue<int>q;
    int st,ed;
    int dist[10005];
    void bfs(int ed)
    {
        cando[ed]=1;
        q.push(ed);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0,j=v[x].size();i<j;i++)
                if(!cando[v[x][i]])
                {
                    cando[v[x][i]]=1;
                    q.push(v[x][i]);
                }
        }
    }
    void spfa(int ed)
    {
        q.push(ed);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0,j=v[x].size();i<j;i++)
                if(er[v[x][i]])
                {
                    q.push(v[x][i]);
                    er[v[x][i]]=0;
                    dist[v[x][i]]=dist[x]+1;
                }
        }
    }
    int main()
    {    
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a==b)
                continue;
            v[b].push_back(a);
        }
        scanf("%d%d",&st,&ed);
        bfs(ed);
        memcpy(er,cando,sizeof(cando));
        for(int i=1;i<=n;i++)
            if(!cando[i])
                for(int j=0,k=v[i].size();j<k;j++)
                    if(er[v[i][j]])
                        er[v[i][j]]=0;
        spfa(ed);
        if(dist[st]==0)
        {
            printf("-1");
            return 0;
        }
        else 
        {
            printf("%d",dist[st]);
            return 0;
        }
    }
    
  • 相关阅读:
    uniDAC 8.4.1一个严重的bug
    Delphi Event Bus进阶(三)如何使用通道?
    从delphi 10.3到delphi 10.4的改变实务
    uniDAC 8.4.1 database is locked
    调整Delphi IDE代码的行间距
    Deployment Manager now Open Source
    Delphi 10.4.2 Android 64位发布格式之App Bundle格式aab
    每日日报79
    每日日报78
    团队冲刺博客(四)
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11782368.html
Copyright © 2011-2022 走看看