a.打标记判断即可

ll n,m,a,b,ans=inf;
bool f;
void solve(){ 
  cin>>a>>b>>n;
  rep(i,1,n){
    ll k;cin>>k>>m;f=0;
    rep(j,1,m){
      int x;cin>>x;
      if(x==a)f=1;
      if(f&&x==b)ans=min(ans,k);
    }
  }
  if(ans==inf)cout<<-1;
  else cout<<ans;
  return;
}

b.开两个数组,表示从a开始到某点的最小距离和从某点到b的最小距离
注意判断不换乘比换乘更优的情况

ll n,m,k,a,b,dis1[N],dis2[N];
ll ans = inf;
void solve(){ 
  cin>>a>>b>>n;
  mset(dis1,inf);mset(dis2,inf);
  dis1[a]=0;dis2[b]=0;
  rep(i,1,n){
    cin>>k>>m;vector<int> tmp(m+1);
    int f1 = 0,f2 = 0;
    rep(i,1,m){
      cin>>tmp[i];
      if(tmp[i]==a)f1=i;
      if(tmp[i]==b)f2=i;
      if(f1&&tmp[i]==b)ans=min(ans,k);
    }
    if(f1)rep(i,f1+1,m)dis1[tmp[i]]=min(dis1[tmp[i]],k);
    if(f2)rep(i,1,f2-1)dis2[tmp[i]]=min(dis2[tmp[i]],k);
  }
  rep(i,1,10000)ans=min(ans,dis1[i]+dis2[i]);
  if(ans==inf)cout<<-1;
  else cout<<ans;
  return;
}

c.类似于双指针的操作.因为我们只关心相对大小,所以没有必要遍历,每次判断一下大小然后让小的+1即可

ll n,m;
void solve(){ 
  string s,t;cin>>s>>t;
  int x = 10,y = 10;
  function<ll(string,int)>c=[&](string st,int r){
    ll res = 0,p = 1;
    per(i,2,0){
      res+=(st[i]-'0')*p;
      p*=r;
    }
    return res;
  };
  while(x<=15000&&y<=15000){
    if(c(s,x)>c(t,y))++y;
    else if(c(s,x)<c(t,y))++x;
    else{ cout<<x<<" "<<y<<'\n';return ;}
  }
  return;
}

d.dfs处理出两人到n的所有可能时间,判断有无重合即可

ll n,m;
vector<pii> edge1[20],edge2[20];
int dis[N];
void dfs1(int p,int t){
  if(p==n)dis[t]=1;
  for(auto c:edge1[p]){
    dfs1(c.fi,t+c.se);
  }
}
void dfs2(int p,int t){
  if(p==n&&dis[t]==1)dis[t]=2;
  for(auto c:edge2[p]){
    dfs2(c.fi,t+c.se);
  }
}
void solve(){ 
  cin>>n>>m;
  rep(i,1,m){
    int u,v,a,b;cin>>u>>v>>a>>b;
    edge1[u].pb({v,a});
    edge2[u].pb({v,b});
  }
  dfs1(1,0);
  dfs2(1,0);
  rep(i,1,500000){
    if(dis[i]==2){
      cout<<i;return ;
    }
  }
    cout<<"IMPOSSIBLE";
  return;
}