共补9题
bdegji略;
F:dijkstra的变形题,从家到打卡点后又回家,是一个有向环,先算从家到打卡点的最短路,然后将所有有向边反转一下,再求此最短路,想加就是这个环的最短路径;
代码略;
H:区间最大值:
比较典型的题目,可以用树状数组或者st表来做;按理来说两种方法都是o(nlogn),不知道为啥st可以,树状数组会超时
做个树状数组求区间最大值(o(nlogn))代码笔记:(过不了题目,超时了)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int n,q,arr[N];
int bitree[N]={0};
int lowbit(int t){
return t&(-t);
}
void add(int i,int n){//时间复杂度o(logn)
if(i==0) return;
while(i<n){
bitree[i]=max(bitree[i],n);
i+=lowbit(i);
}
}
// void update(int i,int k)//时间复杂度o((logn)^2)
// {
// int lb;
// bitree[i]=arr[i]=k;//原数组也要跟着改变,求区间最大值要用
// while(i<=n)
// {
// lb=lowbit(i);
// bitree[i]=arr[i];
// for(int j=1;j<lb;j<<=1)
// bitree[i]=max(bitree[i],bitree[i-j]);
// i+=lowbit(i);
// }
// }
//递归::
// int query(int x,int y){
// if(y-lowbit(y)>x) return max(query(x,y-lowbit(y)),bitree[y]);
// else return max(arr[x],query(x,y-1));
// }
//循环::
int query(int x, int y){
int ans=0;
while(x<=y){
ans=max(ans,arr[y]);
y--;
for(;y-lowbit(y)>x;y-=lowbit(y))
ans=max(ans,bitree[y]);
}
return ans;
}
// int query(int lef,int rig)
// {
// int res=0;
// while(rig>=lef)
// {
// if(rig-lowbit(rig)+1>=lef)
// {
// res=max(res,bitree[rig]);
// rig=rig-lowbit(rig);
// }
// else
// {
// res=max(res,arr[rig]);
// --rig;
// }
// }
// return res;
// }
int main(){
cin>>n;
for(int i=1;i<=n;i++) {
scanf("%d",&arr[i]);
add(i,arr[i]);
}
cin>>q;
while(q--){
int l,r;
cin>>l>>r;
cout<<query(l,r)<<endl;
}
return 0;}
st表求静态数组区间最大值::(cin关流可以AC)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+100;
#define endl '\n'
ll n,q,arr[N];
ll st[N][24]={0};
ll Log2[N]={0};
int query(int l,int r){
int t =log2(r-l+1);
return max(st[l][t],st[r-(1<<t)+1][t]);
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) {
//scanf(" %lld ",&arr[i]);
cin>>arr[i];
}
//预处理st表
for(int i=1;i<=n;i++){
st[i][0]=arr[i];
}
for(int j=1;j<24;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
//为了方便查询,预处log2表||也可以用
//Log2[1]=0;
//for(int i=2;i<=n+1;i++) Log2[i]=Log2[i/2]+1;//向下取整;
cin>>q;
while(q--){
int l,r;
cin>>l>>r;
//int t=Log2[r-l+1];
printf("%d\n",query(l,r));
}
return 0;}
K:经典的最短路径之最大权重的最小值;是dijkstra的变形体(和原本的dij相差较大)dist【N】数组中存的是最短路径中的最大权重;
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef pair<int,int> PII;
const int N=4e4+10,M=4e4+10;
int h[N],ne[M],e[N],w[M],idx=0;
int n,m;
int s,x;
int dist[N];
bool st[N];
void add(int a,int b,int c){
e[idx]=b;ne[idx]=h[a];h[a]=idx;w[idx]=c;idx++;
}
int distra(){
memset(dist,0x3f,sizeof dist);
dist[s]=0;//将s节点当做第一个节点
priority_queue <PII,vector<PII>,greater<PII>> heap;
heap.push({0,s});
while(!heap.empty()){
PII q=heap.top();
heap.pop();
int ver=q.second,dis=q.first;
if(st[ver]) continue;
st[ver]=true;
for(int i=h[ver];i!=-1;i=ne[i]){//这一块是与原版不同的主要地方(重要变化)
int j=e[i];
if(dist[j]>max(dist[ver],w[i])){
dist[j]=max(dist[ver],w[i]);
heap.push({dist[j],j});
}
}
}
return dist[x];//x节点当做第n个结点
}
signed main(){
IOS;
cin>>n>>m;
int u,v,a;
memset(h,-1,sizeof h);
while(m--){
cin>>u>>v>>a;
add(u,v,a);
add(v,u,a);//无向图
}
cin>>s>>x;
cout<<distra()<<endl;
return 0;
}