Iron and Coal(3次bfs)
题意:给一个有向图,然后一些点有铁一些点有煤,然后问从1走,至少花费多少(走一个没走过的点花费1,走过的点再走一次是不用花费的)可以拿到一个铁一个煤,点可以重复走。
思路:枚举从1节点到一个铁一个煤的交叉点即可,三遍bfs处理出dis[1,2,3][i]分别表示1号点到i的最小花费,i到铁的最小花费,i到煤的最小花费。
AC_Code:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e5+10; 5 const int inf = 0x3f3f3f3f; 6 const double pi = acos(-1.0); 7 #define rep(i,first,second) for(ll i=first;i<=second;i++) 8 #define dep(i,first,second) for(ll i=first;i>=second;i--) 9 10 ll n,m,k; 11 ll dis[4][maxn],vis[maxn]; 12 vector<ll>g[maxn],ng[maxn]; 13 void bfs1(){ 14 queue<ll>q; 15 while(!q.empty()) q.pop(); 16 rep(i,1,n+5) vis[i]=0; 17 q.push(1); 18 vis[1]=1; 19 dis[1][1]=0; 20 while( !q.empty() ){ 21 ll u=q.front(),v; 22 q.pop(); 23 for(ll i=0;i<g[u].size();i++){ 24 v=g[u][i]; 25 if( vis[v] ) continue; 26 vis[v]=1; 27 dis[1][v]=dis[1][u]+1; 28 q.push(v); 29 } 30 } 31 } 32 void bfs2(){ 33 queue<ll>q; 34 while( !q.empty()) q.pop(); 35 rep(i,1,n+5) vis[i]=0; 36 q.push(n+1); 37 vis[n+1]=1; 38 dis[2][n+1]=0; 39 while( !q.empty() ){ 40 ll u=q.front(),v; 41 q.pop(); 42 for(ll i=0;i<ng[u].size();i++){ 43 v=ng[u][i]; 44 if( vis[v] ) continue; 45 if( u==n+1 ) dis[2][v]=dis[2][n+1]; 46 else dis[2][v]=dis[2][u]+1; 47 vis[v]=1; 48 q.push(v); 49 } 50 } 51 } 52 void bfs3(){ 53 queue<ll>q; 54 while( !q.empty() ) q.pop(); 55 rep(i,1,n+5) vis[i]=0; 56 q.push(n+2); 57 vis[n+2]=1; 58 dis[3][n+2]=0; 59 while( !q.empty()){ 60 ll u=q.front(),v; 61 q.pop(); 62 for(ll i=0;i<ng[u].size();i++){ 63 v=ng[u][i]; 64 if( vis[v]) continue; 65 if( u==n+2 ) dis[3][v]=dis[3][n+2]; 66 else dis[3][v]=dis[3][u]+1; 67 vis[v]=1; 68 q.push(v); 69 } 70 } 71 } 72 73 int main() 74 { 75 scanf("%lld%lld%lld",&n,&m,&k); 76 rep(i,1,n) dis[1][i]=dis[2][i]=dis[3][i]=inf; 77 rep(i,1,m){ 78 ll o; 79 scanf("%lld",&o); 80 ng[n+1].push_back(o); 81 } 82 rep(i,1,k){ 83 ll c; 84 scanf("%lld",&c); 85 ng[n+2].push_back(c); 86 } 87 rep(i,1,n){ 88 ll tmp,v; 89 scanf("%lld",&tmp); 90 while( tmp-- ){ 91 scanf("%lld",&v); 92 g[i].push_back(v); 93 ng[v].push_back(i); 94 } 95 } 96 bfs1(); 97 bfs2(); 98 bfs3(); 99 ll ans=inf; 100 rep(i,1,n){ 101 ans=min(ans,dis[1][i]+dis[2][i]+dis[3][i]); 102 } 103 if( ans==inf ) puts("impossible"); 104 else{ 105 printf("%lld\n",ans); 106 } 107 return 0; 108 }