zoukankan      html  css  js  c++  java
  • [NOIP2014]寻找道路(图论)

    题目描述

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

    1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。

    2 .在满足条件1 的情况下使路径最短。

    注意:图G 中可能存在重边和自环,题目保证终点没有出边。

    请你输出符合条件的路径的长度。

    输入输出格式

    输入格式:

    输入文件名为road .in。

    第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边。

    接下来的m 行每行2 个整数x 、y ,之间用一个空格隔开,表示有一条边从点x 指向点y 。

    最后一行有两个用一个空格隔开的整数s 、t ,表示起点为s ,终点为t 。

    输出格式:

    输出文件名为road .out 。

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

    输入输出样例

    输入样例#1:
    3 2  
    1 2  
    2 1  
    1 3  
    
    输出样例#1:
    -1
    输入样例#2:
    6 6  
    1 2  
    1 3  
    2 6  
    2 5  
    4 5  
    3 4  
    1 5  
    
    输出样例#2:
    3

    说明

    解释1:

    如上图所示,箭头表示有向道路,圆点表示城市。起点1 与终点3 不连通,所以满足题

    目᧿述的路径不存在,故输出- 1 。

    解释2:

    如上图所示,满足条件的路径为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。

    • noip2014 day2t2,图论题,不过貌似比较简单。
    • 已知只有所有出边都直接或间接指向终点的点才可能被选择,所以就建反边,从终点想起点扫,dfs,bfs均可,在把所有终点不能达到的点打上标记,这些点均不可备选择,并且在反边图中这些点所指向的点也不能被选择(因为在正边图中这些点指向标记点)。因此可以删去图中不符合要求的点,然后跑最短路即可。
    • spfa,heap+dijkstra均可,bfs,dfs复杂度为O(n),spfa复杂度为O(ke),heap+dijkstra复杂度为O(nloge),均可通过该题。
     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 int tot,total,n,m,ss,tt,l[500050],r[500050],pre[500050],last[10050],other[500050];
     7 int que[10050],d[10050];
     8 bool judge[10050],vis[10050],point[10050];
     9 
    10 void add(int u,int v) {
    11     pre[++tot]=last[u];
    12     last[u]=tot;
    13     other[tot]=v;
    14 }
    15 
    16 void bfs(int x) {
    17     int h=0,t=1;
    18     que[1]=x;
    19     vis[x]=1;
    20     point[x]=1;
    21     total++;
    22     while (h<t) {
    23         int cur=que[++h];
    24         for (int p=last[cur]; p; p=pre[p]) {
    25             int q=other[p];
    26             if (!vis[q]) {
    27                 vis[q]=1;
    28                 que[++t]=q;
    29                 total++;
    30                 point[q]=1;
    31             }
    32         }
    33     }
    34 }
    35 
    36 void spfa(int x) {
    37     int h=0,t=1;
    38     que[1]=x;
    39     memset(d,127,sizeof d);
    40     d[x]=0;
    41     while (h<t) {
    42         int cur=que[++h];
    43         vis[cur]=0;
    44         for (int p=last[cur]; p; p=pre[p]) {
    45             int q=other[p];
    46             if (!point[q]) continue; 
    47             if (judge[q]) continue;
    48             if (d[q]>d[cur]+1) {
    49                 d[q]=d[cur]+1;
    50                 if (!vis[q]) {
    51                     vis[q]=1;
    52                     que[++t]=q;
    53                 }
    54             }
    55         }
    56     }
    57 }
    58 
    59 int main() {
    60     scanf("%d%d",&n,&m);
    61     for (int i=1; i<=m; i++) scanf("%d%d",&l[i],&r[i]);
    62     scanf("%d%d",&ss,&tt);
    63     for (int i=1; i<=m; i++) add(r[i],l[i]);
    64     bfs(tt);
    65     if (!point[ss]) {
    66         printf("%d",-1);
    67         return 0;         
    68     }
    69     for (int i=1; i<=n; i++) {
    70         if (point[i]) continue;
    71         for (int p=last[i]; p; p=pre[p]) {
    72             int q=other[p];
    73             judge[q]=1;
    74         }
    75     }
    76     memset(que,0,sizeof que);
    77     memset(vis,0,sizeof vis);
    78     memset(last,0,sizeof last);
    79     tot=0;
    80     for (int i=1; i<=m; i++) add(l[i],r[i]);
    81     spfa(ss);
    82     printf("%d",d[tt]);
    83     return 0;
    84 }
  • 相关阅读:
    (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row
    (二叉树 BFS) leetcode513. Find Bottom Left Tree Value
    (二叉树 BFS DFS) leetcode 104. Maximum Depth of Binary Tree
    (二叉树 BFS DFS) leetcode 111. Minimum Depth of Binary Tree
    (BFS) leetcode 690. Employee Importance
    (BFS/DFS) leetcode 200. Number of Islands
    (最长回文子串 线性DP) 51nod 1088 最长回文子串
    (链表 importance) leetcode 2. Add Two Numbers
    (链表 set) leetcode 817. Linked List Components
    (链表 双指针) leetcode 142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/zoewilly/p/6042893.html
Copyright © 2011-2022 走看看