• 10.22T6 水题


    Description

      在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
      1.路径上的所有点的出边所指向的点都直接或间接与终点连通。 
      2.在满足条件1的情况下使路径最短。 
      注意:图G中可能存在重边和自环,题目保证终点没有出边。 
      请你输出符合条件的路径的长度。

    Input

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

    Output

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

    Sample Input

    3 2 1 2 2 1 1 3

    Sample Output

    -1

    Hint

    road.in
    6 6
    1 2
    1 3
    2 6
    2 5
    4 5
    3 4
    1 5
    road.out
    3
     
     
     
     
     
    反向跑一次记录不能到达的点,然后记录与之相连的点,正向跑一边spfa
    code:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 #define N 1000005
     6 using namespace std;
     7 struct node{
     8     int u,v;
     9 }e[N],e1[N];
    10 int s,t,first[N],nxt[N],cnt;
    11 void add(int u,int v){
    12     e[++cnt].u=u;
    13     e[cnt].v=v;
    14     nxt[cnt]=first[u];
    15     first[u]=cnt;
    16 }
    17 int first1[N],nxt1[N],cnt1;
    18 void add1(int u,int v){
    19     e1[++cnt1].u=u;
    20     e1[cnt1].v=v;
    21     nxt1[cnt1]=first1[u];
    22     first1[u]=cnt1;
    23 }
    24 int vis[N],dis[N],visit[N];
    25 void dfs(int x){
    26     visit[x]=1;
    27     for(int i=first[x];i;i=nxt[i]){
    28         int v=e[i].v;
    29         if(visit[v])continue;
    30         dfs(v);
    31     }
    32 }
    33 int check[N];
    34 void spfa(){
    35     queue<int>q;
    36     memset(dis,0x3f3f3f3f,sizeof dis);
    37     memset(vis,0,sizeof vis);
    38     vis[s]=1;
    39     dis[s]=0;
    40     q.push(s);
    41     while(!q.empty()){
    42         int u=q.front();
    43         q.pop();
    44         vis[u]=0;
    45     //    cout<<u<<":from"<<'
    ';
    46         for(int i=first1[u];i;i=nxt1[i]){
    47             int v=e1[i].v;
    48     //        cout<<v<<":to"<<'
    ';
    49             if(check[v])continue;
    50             if(dis[v]>dis[u]+1){
    51                 dis[v]=dis[u]+1;
    52                 if(!vis[v]){
    53                     vis[v]=1;
    54                     q.push(v);
    55                 }
    56             }
    57         }
    58     }
    59 }
    60 long long read(){
    61     long long x=0,f=1;
    62     char c=getchar();
    63     while(!isdigit(c)){
    64         if(c=='-')f=-1;
    65         c=getchar();
    66     }
    67     while(isdigit(c)){
    68         x=(x<<3)+(x<<1)+c-'0';
    69         c=getchar();
    70     }
    71     return x*f;
    72 }
    73 int main(){
    74     int n,m;
    75     n=read(),m=read();
    76     for(int i=1;i<=m;i++){
    77         int u,v;
    78         u=read(),v=read();
    79         add(v,u);
    80         add1(u,v);
    81     }
    82     s=read(),t=read();
    83     dfs(t);
    84     for(int i=1;i<=n;i++){
    85         if(visit[i])continue;
    86         check[i]=1;
    87         for(int j=first[i];j;j=nxt[j]){
    88             int v=e[j].v;
    89             check[v]=1;
    90         }
    91     }
    92 //    for(int i=1;i<=n;i++)cout<<check[i]<<'
    ';
    93     spfa();
    94     cout<<(dis[t]==0x3f3f3f3f?-1:dis[t]);
    95     return 0;
    96 }

    over

  • 相关阅读:
    点击事件在label标签执行2次解决办法
    关于有偿提供拼图响应式后台的通知.
    jquery鼠标悬停导航下划线滑出效果
    javascript深层解释。
    创业者靠什么成功?
    怎么样才是理想的程序员?
    web总结。
    深入认识盒子模型 display:inline-block BFC 和haslayout !
    25种用户十秒离开你网站的原因!
    JavaScript 引用类型数组!
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9833426.html
Copyright © 2020-2023  润新知