洛谷 P2296 尋找道路 題解

每日一題 day42 打卡node

Analysis

首先,預處理,把每條邊反向。ios

從終點開始bfs,標記從終點開始能夠走到的點。git

第二步,枚舉每個點,若是這個點沒有被標記,則枚舉它的每一條出邊(反向後的),若是它指向的點被標記,則說明這個被標記的點不合法,刪除。spa

第三步,在合法點上bfs,單源最短路。找到答案。code

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #define int long long
  7 #define maxm 200000+10
  8 #define maxn 10000+10
  9 #define xb return
 10 #define xh 0
 11 #define sty ;
 12 #define rep(i,s,e) for(register int i=s;i<=e;++i)
 13 #define dwn(i,s,e) for(register int i=s;i>=e;--i) 
 14 using namespace std;
 15 inline int read()
 16 {
 17     int x=0;
 18     bool f=1;
 19     char c=getchar();
 20     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
 21     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
 22     if(f) return x;
 23     return 0-x;
 24 }
 25 inline void write(int x)
 26 {
 27     if(x<0){putchar('-');x=-x;}
 28     if(x>9)write(x/10);
 29     putchar(x%10+'0');
 30 }
 31 int n,m,cnt1,cnt2,s,t;
 32 int head1[maxm],head2[maxm];
 33 bool book[maxn],book1[maxn],mark[maxn];
 34 struct node1
 35 {
 36     int v,nex;
 37 }edge1[maxm];
 38 struct node2
 39 {
 40     int v,nex;
 41 }edge2[maxm];
 42 inline void add1(int x,int y)
 43 {
 44     edge1[++cnt1].v=y;
 45     edge1[cnt1].nex=head1[x];
 46     head1[x]=cnt1;
 47 }
 48 inline void add2(int x,int y)
 49 {
 50     edge2[++cnt2].v=y;
 51     edge2[cnt2].nex=head2[x];
 52     head2[x]=cnt2;
 53 }
 54 void bfs_back(int start)
 55 {
 56     queue<int> q;
 57     q.push(start);
 58     book[start]=1;
 59     while(!q.empty())
 60     {
 61         int from=q.front();
 62         q.pop();
 63         for(int i=head2[from];i;i=edge2[i].nex)
 64         {
 65             int to=edge2[i].v;
 66             if(book[to]==1) continue;
 67             book[to]=1;
 68             q.push(to);
 69         }
 70     }
 71 }
 72 int bfs_top(int start)
 73 {
 74     queue<pair<int,int> > q;
 75     q.push(make_pair(start,0));
 76     mark[start]=1;
 77     int flag=0;
 78     while(!q.empty())
 79     {
 80         int from=q.front().first,val=q.front().second;
 81         q.pop();
 82         if(from==t) 
 83         {
 84             flag=1;
 85             return val;
 86         }
 87         for(int i=head1[from];i;i=edge1[i].nex)
 88         {
 89             int to=edge1[i].v;
 90             if(mark[to]==1||book1[to]==0) continue;
 91             mark[to]=1;
 92             q.push(make_pair(to,val+1));
 93         }
 94     }
 95     if(flag==0) return -1;
 96 }
 97 signed main()
 98 {
 99     n=read();m=read();
100     rep(i,1,m) 
101     {
102         int x=read(),y=read();
103         add1(x,y);
104         add2(y,x);
105     }
106     s=read();t=read();
107     bfs_back(t);
108     if(book[s]==0)
109     {
110         write(-1);
111         xb xh sty
112     }
113     rep(i,1,n)
114         if(book[i]==1)
115         {
116             book1[i]=1;
117             int from=i;
118             for(int j=head1[from];j;j=edge1[j].nex)
119             {
120                 int to=edge1[j].v;
121                 if(book[to]==0)
122                 {
123                     book1[from]=0;
124                     break;
125                 }
126             }
127         }
128     if(book1[s]==0) 
129     {
130         write(-1);
131         xb xh sty
132     }
133     int ans=bfs_top(s);
134     write(ans);
135     xb xh sty
136 }

請各位大佬斧正(反正我不認識斧正是什麼意思)blog