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;
}