Guest User

Untitled

a guest
Apr 24th, 2021
691
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.71 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define ll long long
  5. #define ii pair<int,int>
  6. #define iii pair<int,ii>
  7. #define fi first
  8. #define se second
  9. #define endl '\n'
  10.  
  11. #define puf push_front
  12. #define pof pop_front
  13. #define pub push_back
  14. #define pob pop_back
  15.  
  16. #define rep(x,s,e) for (auto x=s-(s>e);x!=e-(s>e);(s<e)?x++:x--)
  17. #define all(x) (x).begin(),(x).end()
  18. #define sz(x) (int) (x).size()
  19.  
  20. int n,m,k;
  21. vector<ii> edges;
  22.  
  23. const int EXT=1000000; //extra stuff for connecting 2 watchmen
  24. vector<int> w[250005+EXT]; //period is implicit here
  25. vector<int> al[250005+EXT];
  26.  
  27. priority_queue<iii,vector<iii>,greater<iii> > pq;
  28. int upt[250005+EXT]; //time to update upwards
  29.  
  30. int id[250005+EXT]; //which watchmen
  31. int bad[250005+EXT]; //when the watchmen comes
  32. int ped[250005+EXT]; //period
  33. int out[250005];
  34.  
  35. vector<ii> dial[10000005];
  36.  
  37. void read(int &x){
  38.     x=0;
  39.     char ch=getchar_unlocked();
  40.     while (ch&16){
  41.         x=(x<<3)+(x<<1)+(ch&15);
  42.         ch=getchar_unlocked();
  43.     }
  44. }
  45.  
  46. int fix(int i,int j){
  47.     i%=j;
  48.     if (i<0) i+=j;
  49.     return i;
  50. }
  51.  
  52. void upd(int k,int i,int j){
  53.     if (w[i][j]>k){
  54.         w[i][j]=k;
  55.         //pq.push(iii(k,ii(i,j)));
  56.         if (k>10000000) return;
  57.         dial[k].pub(ii(i,j));
  58.     }
  59. }
  60.  
  61. int main(){
  62.     cin.tie(0);
  63.     cout.tie(0);
  64.     cin.sync_with_stdio(false);
  65.    
  66.     read(n),read(m);
  67.    
  68.     int a,b;
  69.     rep(x,0,m){
  70.         read(a),read(b);
  71.         edges.pub(ii(a,b));
  72.     }
  73.    
  74.     memset(ped,-1,sizeof(ped));
  75.     memset(id,-1,sizeof(id));
  76.     memset(bad,-1,sizeof(bad));
  77.    
  78.     read(k);
  79.     rep(x,0,k){
  80.         read(a);
  81.        
  82.         vector<int> path;
  83.         rep(y,0,a){
  84.             read(b);
  85.            
  86.             path.pub(b);
  87.             bad[b]=y;
  88.             id[b]=x;
  89.             ped[b]=a;
  90.             upt[b]=1;
  91.         }
  92.     }
  93.    
  94.     int IDX=n+1;
  95.    
  96.     rep(x,1,n+1) if (ped[x]!=-1){
  97.         out[x]=IDX;
  98.         al[x].pub(out[x]);
  99.         IDX++;
  100.     }
  101.    
  102.     for (auto &it:edges){
  103.         tie(a,b)=it;
  104.         if (id[a]>id[b]) swap(a,b);
  105.         //cout<<id[a]<<" "<<id[b]<<endl;
  106.        
  107.         if (id[a]!=-1 && id[b]!=-1 && id[a]!=id[b]){
  108.             al[a].pub(IDX);
  109.             al[IDX].pub(b);
  110.             ped[IDX]=ped[b];
  111.             upt[IDX]=ped[a];
  112.             IDX++;
  113.            
  114.             al[b].pub(IDX);
  115.             al[IDX].pub(a);
  116.             ped[IDX]=ped[a];
  117.             upt[IDX]=ped[b];
  118.             IDX++;
  119.         }
  120.         else if (id[a]==-1 && id[b]!=-1){
  121.             al[a].pub(b);
  122.             al[out[b]].pub(a);
  123.         }
  124.         else{
  125.             al[a].pub(b);
  126.             al[b].pub(a);
  127.         }
  128.     }
  129.    
  130.     rep(x,0,IDX){
  131.         if (ped[x]==-1) w[x].pub(1e9);
  132.         else{
  133.             rep(y,0,ped[x]) w[x].pub(1e9);
  134.         }
  135.     }
  136.    
  137.     upd(0,1,0);
  138.    
  139.     int weight=0;
  140.     while (weight<10000000){
  141.         if (dial[weight].empty()){
  142.             weight++;
  143.             continue;
  144.         }
  145.        
  146.         int n1,n2;
  147.         tie(n1,n2)=dial[weight].back();
  148.         dial[weight].pob();
  149.        
  150.         if (w[n1][n2]!=weight) continue;
  151.         if (ped[n1]!=-1 && weight%ped[n1]==bad[n1]) continue;
  152.         //same position as watchmen
  153.        
  154.         //cout<<weight<<" "<<n1<<" "<<n2<<" "<<ped[n1]<<" "<<bad[n1]<<endl;
  155.        
  156.         for (auto it:al[n1]){
  157.             if (ped[it]==-1){ //this is a problem....
  158.                 int ww=weight;
  159.                 if (n1<=n) ww++;
  160.                 upd(ww,it,0);
  161.             }
  162.             else if (ped[n1]==-1 && ped[it]!=-1){ //update all
  163.                 // we have to optmize this part...
  164.                 int ww=weight+1;
  165.                 upd(ww,it,ww%ped[it]);
  166.                
  167.                 //also need one that lands immediately after watchmen pass
  168.                 ww=weight+fix(bad[it]-weight,ped[it])+1;
  169.                 //cout<<weight<<" "<<ww<<" "<<ped[it]<<" "<<bad[it]<<endl;
  170.                 upd(ww,it,ww%ped[it]);
  171.             }
  172.             else if (id[n1]==id[it]){
  173.                 int ww=weight+1;
  174.                
  175.                 if ((bad[it]+1)%ped[it]==bad[n1] && ww%ped[it]==bad[n1]) continue;
  176.                 upd(ww,it,ww%ped[it]);
  177.             }
  178.             else{
  179.                 int ww=weight;
  180.                 if (n1<=n) ww++;
  181.                
  182.                 upd(ww,it,ww%ped[it]);
  183.             }
  184.         }
  185.        
  186.         if (ped[n1]!=-1){
  187.             int ww=weight+upt[n1];
  188.             upd(ww,n1,ww%ped[n1]);
  189.         }
  190.     }
  191.    
  192.    
  193.     /*
  194.     rep(x,1,IDX){
  195.         cout<<x<<": ";
  196.         for (auto &it:w[x]) cout<<it<<" "; cout<<endl;
  197.     }
  198.     //*/
  199.    
  200.     if (w[n][0]==1e9) cout<<"impossible"<<endl;
  201.     else cout<<w[n][0]<<endl;
  202. }
  203.  
Advertisement
Add Comment
Please, Sign In to add comment