zoukankan      html  css  js  c++  java
  • 洛谷 2296 寻找道路

    【题解】

      先建反向图,dfs求出哪些点可以到达终点。

      再建正向图,dfs求出哪些点可以作为路径上的点。

      最后在合法的点之间连边,跑dijkstra.

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define LL long long
     5 #define rg register
     6 #define N 10010
     7 #define M 200010
     8 using namespace std;
     9 int n,m,tot,st,ed,fa,son,last[N],dis[N],pos[N];
    10 bool arr[N],ok[N],vis[N];
    11 struct edge{int to,pre;}e[M];
    12 struct heap{int p,d;}h[N];
    13 struct rec{int u,v;}r[M];
    14 inline int read(){
    15     int k=0,f=1; char c=getchar();
    16     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    17     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    18     return k*f;
    19 }
    20 void dfs(int x){
    21     arr[x]=1;
    22     for(rg int i=last[x],to;i;i=e[i].pre)if(!arr[to=e[i].to]) dfs(to);
    23 }
    24 void dfs2(int x){
    25     vis[x]=1; bool can=1;
    26     for(rg int i=last[x],to;i;i=e[i].pre){
    27         if(!arr[to=e[i].to]) can=0;
    28         if(!vis[to]) dfs2(to);
    29     }
    30     ok[x]=can&arr[x];
    31 }
    32 inline void up(int x){
    33     while((fa=x>>1)&&h[fa].d>h[x].d) swap(h[x],h[fa]),swap(pos[h[x].p],pos[h[fa].p]),x=fa;
    34 }
    35 inline void down(int x){
    36     while((son=x<<1)<=tot){
    37         if(h[son+1].d<h[son].d&&son<tot) son++;
    38         if(h[son].d<h[x].d) swap(h[son],h[x]),swap(pos[h[son].p],pos[h[x].p]),x=son;
    39         else return;
    40     }
    41 }
    42 void dijkstra(int x){
    43     for(rg int i=1;i<=n;i++) dis[i]=1e9;
    44     h[tot=pos[x]=1]=(heap){x,dis[x]=0};
    45     while(tot){
    46         int now=h[1].p; pos[h[tot].p]=1; h[1]=h[tot--]; if(tot) down(1);
    47         for(rg int i=last[now],to;i;i=e[i].pre)if(dis[to=e[i].to]>dis[now]+1){
    48             dis[to]=dis[now]+1;
    49             if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]};
    50             else h[pos[to]].d=dis[to];
    51             up(pos[to]);
    52         }
    53     }
    54 }
    55 int main(){
    56     n=read(); m=read();
    57     for(rg int i=1,u,v;i<=m;i++){
    58          u=r[i].u=read(),v=r[i].v=read();
    59          e[++tot]=(edge){u,last[v]}; last[v]=tot;
    60     }
    61     st=read(); ed=read();
    62     dfs(ed);
    63 //    for(rg int i=1;i<=n;i++) printf("%d ",arr[i]); puts("arr");
    64     
    65     memset(last,0,sizeof(last)); tot=0;
    66     for(rg int i=1;i<=m;i++){
    67         int u=r[i].u,v=r[i].v;
    68         e[++tot]=(edge){v,last[u]}; last[u]=tot;
    69     }
    70     dfs2(st); ok[ed]=1;
    71 //    for(rg int i=1;i<=n;i++) printf("%d ",ok[i]); puts("ok");
    72     if(!ok[st]){puts("-1"); return 0;}
    73     
    74     memset(last,0,sizeof(last)); tot=0;
    75     for(rg int i=1,u,v;i<=m;i++)if(ok[u=r[i].u]&&ok[v=r[i].v])
    76         e[++tot]=(edge){v,last[u]},last[u]=tot;
    77     dijkstra(st);
    78     if(dis[ed]!=1e9) printf("%d
    ",dis[ed]);
    79     else puts("-1");
    80     return 0; 
    81 }
  • 相关阅读:
    linux sysfs (2)
    微软——助您启动云的力量网络虚拟盛会
    Windows Azure入门教学系列 全面更新啦!
    与Advanced Telemetry创始人兼 CTO, Tom Naylor的访谈
    Windows Azure AppFabric概述
    Windows Azure Extra Small Instances Public Beta版本发布
    DataMarket 一月内容更新
    和Steve, Wade 一起学习如何使用Windows Azure Startup Tasks
    现实世界的Windows Azure:与eCraft的 Nicklas Andersson(CTO),Peter Löfgren(项目经理)以及Jörgen Westerling(CCO)的访谈
    正确使用Windows Azure 中的VM Role
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9886090.html
Copyright © 2011-2022 走看看