当前位置: 首页 > news >正文

【牛客网】

目录

  • 知识框架
  • No.1 前缀和
    • NC14556:数圈圈
    • NC14600:珂朵莉与宇宙
    • NC21195 :Kuangyeye and hamburgers
    • NC19798:区间权值
    • NC16730:run
    • NC15035:送分了qaq
  • No.2 字符串:
    • 小知识点:
    • 基于KMP算法的字符串匹配:
    • AC自动机:
    • 字符串hash:
    • 后缀自动机:
  • No.3 栈
    • NC15029:吐泡泡
    • NC50998:括号画家
    • NC15975:小c的记事本
    • NC14666:最优屏障
    • NC14847:Masha与老鼠:
    • NC50999:表达式计算
  • No.4 最短路径
    • Bellman-Ford算法
    • Dijkstra算法/Dijkstra + 优先队列的优化
    • floyd-Warshall算法
    • SPFA
    • NC14369:最短路:很直接
    • NC15522:武 :很直接
    • NC15549:小木乃伊到我家
    • NOI1997:最优乘车
    • NC22947:香甜的黄油
    • NC17511:公交线路
    • NC14292:Travel

知识框架

No.1 前缀和

NC14556:数圈圈

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 1001000
long long n,m,t,k,d;
long long x,y,z;
char ch;
string str;
vector<int>v[N];
int num[10]={1,0,0,0,1,0,1,0,2,1}; //0~9
int onum[N+1];
int s[N+1];
void Init(){for(int i=1;i<=N;i++){str=to_string(i);for(auto ss:str){int num1=ss-'0';onum[i]+=num[num1];}}s[1]=0;for(int i=2;i<=N;i++){s[i]=s[i-1]+onum[i];}
}
int main()
{Init();cin>>n;for(int i=0;i<n;i++){cin>>x>>y;cout<<s[y]-s[x-1]<<endl;}return 0;
}

NC14600:珂朵莉与宇宙

//巧妙地利用求平方 变化为减去平方看差是否存在:
//通过指针的指向,那么一串数组中的任意子区间就可以用 两个前缀和 进行 相减 得到:#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,t,k,d;
long long x,y,z,c;
char ch;
string str;
vector<int>v[N];
int s[N+1];int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>x;s[i]=s[i-1]+x;}int res=0;int cnt[N];cnt[0]=1;    //前缀和为0的表示 直接前面n个为平方和了//以每一个右边的端点为指针for(int i=1;i<=n;i++){//找到所有可能的平方和://处理第i个前缀和的所有完全平方数for(int j=0;j*j<=s[i];j++){c=s[i]-j*j;         //假设前面有前缀和==c的; 即if(cnt[c]>0){       //如果前面有前缀和==c的 代表有子区间为j*j;res+=cnt[c];}}cnt[ s[i] ]++;   // 已处理过的这个端点,加入到cnt里面  表示前面的 前缀和为s[i] 的前缀和的个数加一}cout<<res;return 0;
}

NC21195 :Kuangyeye and hamburgers

//vector 的 排序 比如降序:  sort(v.rbegin(),v.rend());
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,t,k,d;
long long x,y,z,c;
char ch;
string str;
vector<int>v[N];
int s[N+1]={0};int main()
{cin>>n>>m;vector<int>ans;for(int i=1;i<=n;i++){cin>>x;ans.push_back(x);}sort(ans.rbegin(),ans.rend());for(int i=0;i<ans.size();i++){s[i+1]=s[i]+ans[i];}int res=0;while(m--){cin>>x>>y;res=max(res,s[y]-s[x-1]);}cout<<res<<endl;return 0;
}

NC19798:区间权值

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,t,k,d;
long long x,y,z,c;
char ch;
string str;
vector<int>v[N];
int s[N+1]={0};
int w[N+1];
int leijia(int l,int r){return (s[r]-s[l-1])*w[r-l+1];
}
int main()
{cin>>n;for(int i=1;i<=n;i++){cin>>x;s[i]=s[i-1]+x;}for(int i=1;i<=n;i++){cin>>w[i];}//下面这个双层循环了导致时间复杂度很高:long long res=0;for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){res=res+leijia(i,j);}}//将 j 的那部分再进行前缀和:因此要把过程改写:for(int j=1;j<=n;j++){}cout<<res%(1000000000+7);return 0;
}

NC16730:run

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int N=1e5+5;
long long n,m,t,k,d,q;
long long x,y,z,c;
char ch;
string str;
vector<int>v[N];
const int  mod=1e9+7;
// 这里的结果如果是  dp[N][3]  就会出错:
long long dp[N][2],ans[N];
int main()
{cin>>q>>k;dp[0][0]=1;for(int i=1;i<=N;i++){dp[i][0]=(dp[i-1][0]+dp[i-1][1])%mod; //以走一米的方式走到i米的时候,可能情况只能是走i-1米的情况总和;if(i-k>=0){dp[i][1]=dp[i-k][0];                 // because not can continue two meters run;only one 情况}ans[i]=(ans[i-1]+dp[i][0]+dp[i][1])%mod;}for(int i=1;i<=q;i++){cin>>x>>y;cout<<(ans[y]-ans[x-1]+mod)%mod<<endl;}return 0;
}// 下面是正确的:
#include <bits/stdc++.h>
using namespace std;const int N = 1e5 + 5;
const int M = 1e9 + 7;int dp[N][2], s[N];int main() {int q, k, l, r;scanf("%d%d", &q, &k);dp[0][0] = 1;for (int i = 1; i <= N; i++) {dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % M;if (i >= k) {dp[i][1] = dp[i - k][0];}s[i] = (s[i - 1] + dp[i][0] + dp[i][1]) % M;}while (q--) {scanf("%d%d", &l, &r);printf("%d\n", (s[r] - s[l - 1] + M) % M);}return 0;
}

NC15035:送分了qaq

经典基础:对x经行分位数处理,直到没有位数

#include<stdio.h>
int check(int x)
{int t=0;while(x > 0)//对x经行分位数处理,直到没有位数{if(x % 10 == 3){return 1;//如果已经有1接下来的位数便不用再判断了,直接可以return 1了}x /= 10;}return 0;
}
#include <stdio.h>
int main()
{int m,n;while(scanf("%d%d",&n,&m)!=EOF){if (m == 0 && n == 0)break;int ans=0;for(int i=n;i<=m;i++){int x=i;while(x){if(x%10==4||x%100==38) {ans++;break;}x/=10;}}printf("%d\n",ans);}} 

No.2 字符串:

初始模板:

//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
int n,m,k,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];int main() {return 0;
}

小知识点:

str.substr(i,n) : 注意不能越界;; 必须判断以下跳出

基于KMP算法的字符串匹配:

暴力搜索:

  • 暴力算法:自己的想法;就是找到第一个相匹配之后就直接转换对象看小字符串去,就想那个断痕那个,先确定小字符串大小然后for便利到该大小记得加循环跳出时间,还有就是字符串可以substr(应该会快一点吗?)

AC自动机:

字符串hash:

后缀自动机:

No.3 栈

NC15029:吐泡泡

//全对的
#include<iostream>
#include<string>
#include<stack>using namespace std;int main()  // stack 写法
{string str;while(cin >> str){stack<char> st, sk; for(auto ch : str){if(st.size()){auto top = st.top();bool flag = 1;while(ch == top){if(ch == 'o'){st.pop();ch = 'O';  }else{st.pop();flag = 0;break;}if(!st.size()) break;top = st.top();}if(flag) st.push(ch);}else{st.push(ch);}}//输出while(st.size()){sk.push(st.top());st.pop();}while(sk.size()){cout << sk.top();sk.pop();}puts("");}return 0;
}//  对了 百分之四十。
//对于N要进行适应性的更改,对于字段错误#include<bits/stdc++.h>using namespace std;#define inf 0x3f3f3f3f#define N 100100int n,m,k,g,d;int x,y,z;char ch;string str;int main() {cin>>str;stack<char>b;vector<char>a;for(auto i:str){a.push_back(i);}for(int i=0;i<a.size();i++){if(b.size()>0){char ss;ss=b.top();if(ss==a[i]&&ss=='o'){b.pop();a[i]='O';i--;}else if(ss==a[i]&&ss=='O'){b.pop();}else{b.push(a[i]);}}else{b.push(a[i]);}}vector<char>c;while(!b.empty()){c.push_back(b.top());b.pop();}reverse(c.begin(),c.end());for(auto i:c){cout<<i;}return 0;}

NC50998:括号画家

例如 (){} 是美观的括号序列,而 )({)[}]( 则不是。

思路:就是先用i指针 指着开始部位。  再有j指针循环以i起头的可能。//对于N要进行适应性的更改,对于字段错误#include<bits/stdc++.h>using namespace std;#define inf 0x3f3f3f3f#define N 100100int n,m,k,g,d;int x,y,z;string str;int main() {cin>>str;int res=0;//类似双指针了好像;for(int i=0;i<str.size();i++){stack<char>st;for(int j=i;j<str.size();j++){if(str[j]=='['){st.push(']');}else if(str[j]=='{'){st.push('}');}else if(str[j]=='('){st.push(')');}else if(st.empty() || str[j]!=st.top()){//夭折break;}else{st.pop();//清空代表在此刻是 对称的。if(st.empty())res=max(res,j-i+1);}}}cout<<res<<endl;return 0;}

NC15975:小c的记事本

// 自己用 char
//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,k,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];int main() {ios::sync_with_stdio(false);cin>>n;stack<vector<char>>ans;vector<char>st;while(n--){cin>>x;if(x==1){ans.push(st);cin>>str;for(auto p:str){st.push_back(p);}}else if(x==2){ans.push(st);cin>>k;while(k--){st.pop_back();}}else if(x==3){cin>>k;cout<<st[k-1]<<endl;}else if(x==4){st=ans.top();ans.pop();}}return 0;
}// 别人用 string
#include<bits/stdc++.h>
using namespace std;
int main()
{ios::sync_with_stdio(false);int t;while(cin>>t){stack<string>s; //定义一个字符串类型的栈 int a;string s1;s.push("");while(t--){cin>>a;if(a==1){cin>>s1;s.push(s.top()+s1); //向记事本插入字符串 }else if(a==2){int k;cin>>k;s1=s.top();s.push(s1.substr(0 , s1.length()-k));}else if(a==3){int k;cin>>k;s1=s.top();cout<<s1[k-1]<<endl; } else s.pop();}}return 0;
}

NC14666:最优屏障

//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
long long n,m,k,g,d,t;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int num(vector<int>h , int l, int r){if(l==r)return 0;int res=0;int maxx=0;for(int i=l;i<=r;i++){maxx=0;for(int j=i+1;j<=r;j++){if(maxx<min(h[i-1],h[j-1]))res++;maxx=max(maxx,h[j-1]);}}return res;}
int main() {cin>>t;for(int i=1;i<=t;i++){cin>>n;vector<int>h;for(int j=0;j<n;j++){cin>>x;h.push_back(x);}int sum=num(h,1,n);vector<int>cnt;cnt.push_back(0);cnt.push_back(0);for(int j=2;j<=n;j++){int zuo=num(h,1,j-1);int you=num(h,j,n);cnt.push_back(sum-zuo-you);}int maxxx=0;int weizhi=0;for(auto p:cnt)maxxx=max(maxxx,p);for(int j=0;j<cnt.size();j++){if(cnt[j]==maxxx){weizhi=j;break;}}cout<<"Case #"<<i<<": "<<weizhi<<" "<<maxxx<<endl;}   return 0;
}

NC14847:Masha与老鼠:


NC50999:表达式计算

#include<bits/stdc++.h>using namespace std;
char s[50];
stack<int>s1;
stack<char>s2;int level(char op){if(op=='+'||op=='-')return 1;else if(op=='*'||op=='/')return 2;else if(op=='^')return 3;return 0;
}int Pow(int a,int b){int res=1;while(b--){res*=a;}return res;
}void calc(char op){int x,y;x=s1.top();s1.pop();y=s1.top();s1.pop();if(op=='+')s1.push(x+y);else if(op=='-')s1.push(y-x);else if(op=='*')s1.push(x*y);else if(op=='/')s1.push(y/x);else if(op=='^')s1.push(Pow(y,x));
}int main(){cin>>s+1;int n=strlen(s+1),num=0;s1.push(0);for(int i=1;i<=n;i++){if(s[i]>='0'&&s[i]<='9'){num=num*10+s[i]-'0';if(s[i+1]<'0'||s[i+1]>'9'){s1.push(num);num=0;}continue;}if(s[i]=='('){s2.push(s[i]);}else{if(s[i]==')'){while(!s2.empty()&&s2.top()!='('){calc(s2.top());s2.pop();}if(!s2.empty()&&s2.top()=='(')s2.pop();}else{while(!s2.empty()&&level(s[i])<=level(s2.top())){calc(s2.top());s2.pop();}s2.push(s[i]);}}}while(!s2.empty()&&s2.top()!='('&&s2.top()!=')'){calc(s2.top());s2.pop();}cout<<s1.top()<<endl;return 0;
}

No.4 最短路径

最短路算法详解_weixin_34018202的博客-CSDN博客

1:两种存储方式:因为邻接表没有 前向星可观,所以 :邻接矩阵+前向星

NC14501:大吉大利,晚上吃鸡:最短路+动态规划

Bellman-Ford算法

Dijkstra算法/Dijkstra + 优先队列的优化

NC20131:飞行路线

//这个k层免费 不是简单的先找到最短,然后去掉k个最大的;

floyd-Warshall算法

SPFA

1:链式前向星:

其中edge[ ] .to表示第i条边的终点, edge[i] .next表示与第i条边同起点的下一条边的存储位置,edge[i] .w为边权值.
另外还有一个数组head[ ],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实
在以i为起点的所有边的最后输入的那个编号.
head[]数组一般初始化为-1,对于加边的add函数是这样的:

下面是对链式前向星的讲解:注意那个 head[u] = cnt++;//更新以u为起点上一条边的编号 是先赋值,再 累加的;

链式前向星–最通俗易懂的讲解_sugarbliss的博客-CSDN博客_链式前向星

NC14369:最短路:很直接

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100100
int n,m,k,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int mp[2000+1][20000+1];
int vis[N];
int dist[N];
int to[N],w[N],head[N]={-1},ne[N],idx=0;
//vis数组标记了节点v是否在Q中
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x]; //这条边的上一条边head[x]=idx++;     // 这个点的最后一条边为: idx表示边
}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[1]=0;vis[1]=1;queue<int>q;q.push(1);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){//遍历以x为起点的所有的边;toint i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}
}int main() {memset(head,-1,sizeof(head));cin>>n>>m;while(m--){cin>>x>>y>>z;add(x,y,z);}spfa();for(int i=2;i<=n;i++){cout<<dist[i]<<endl;}return 0;
}

NC15522:武 :很直接

//注意 链式前向星的 如果是无向图 需要两次 add  且 数据的N边数要乘以2
//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100010
int n,m,k,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int dist[N],vis[N];
int to[N*2],head[N*2]={-1},ne[N*2],w[N*2];//这个因为是无向图;双向
int idx=0;
int p;
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x];head[x]=idx++;}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[p]=0;vis[p]=1;queue<int>q;q.push(p);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){int i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}
}
int main() {memset(head,-1,sizeof(head));cin>>n>>p>>k;for(int i=1;i<=n-1 ;i++){cin>>x>>y>>z;add(x,y,z);add(y,x,z);}spfa();sort(dist+1,dist+1+n);cout<<dist[k+1]<<endl;//离得最短的是本身为0的return 0;
}

NC15549:小木乃伊到我家

//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 200010
int n,m,k,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int dist[N],vis[N];
int to[N*2],head[N*2]={-1},ne[N*2],w[N*2];//这个因为是无向图;双向
int idx=0;
int p;
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x];head[x]=idx++;}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[p]=0;vis[p]=1;queue<int>q;q.push(p);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){int i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}}
int main() {memset(head,-1,sizeof(head));cin>>n>>m;p=1;//出发点while(m--){cin>>x>>y>>z;add(x,y,z);add(y,x,z);}spfa();if(dist[n]==inf)cout<<"qwb baka"<<endl;else cout<<dist[n]<<endl;return 0;
}

NOI1997:最优乘车

对于:stringstream ss 等的用法;;

int main(){string s = "1 23 # 4";stringstream ss;ss<<s;while(ss>>s){cout<<s<<endl;int val = convert<int>(s);cout<<val<<endl;}return 0;
}
输出:1 1 23 23 # 0 4 4

//第一种方法:用bfs 函数类似;//第二种类比距离:该条路线距离为0  换乘一次能达到的为距离为1 的点;所以最终结果要-1;下面用的是这个
// 类比化距离;;
//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 200010
int n,m,k,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int dist[N],vis[N],stop[N];
int to[N*2],head[N*2]={-1},ne[N*2],w[N*2];//这个因为是无向图;双向
int idx=0;
int p;//开始的地方:
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x];head[x]=idx++;}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[p]=0;vis[p]=1;queue<int>q;q.push(p);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){int i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}}
int main() {memset(head,-1,sizeof(head));cin>>m>>n;getchar();while(m--){getline(cin,str);stringstream ssin(str);int cnt=0;while(ssin>>p)stop[cnt++]=p;for(int i=0;i<cnt;i++){for(int j=i+1;j<cnt;j++){add(stop[i],stop[j],1);}}}p=1;//开始spfa();if(dist[n]==inf)cout<<"NO"<<endl;else cout<<dist[n]-1<<endl;return 0;
}

NC22947:香甜的黄油

//问题是:图中已经确定的几点到 图中某一点的最短距离;
// 即 dist[c1]+dist[c2]+...+dist[cn]//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 200010
int n,m,k,c[N],g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int dist[N],vis[N],stop[N];
int to[N*2],head[N*2]={-1},ne[N*2],w[N*2];//这个因为是无向图;双向
int idx=0;
int p;//开始的地方:
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x];head[x]=idx++;}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[p]=0;vis[p]=1;queue<int>q;q.push(p);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){int i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}}
int main() {memset(head,-1,sizeof(head));int res=inf;cin>>d>>n>>m;for(int i=1;i<=d;i++){cin>>c[i];}while(m--){cin>>x>>y>>z;add(x,y,z);add(y,x,z);}for(int i=1;i<=n;i++){//以i为起点p=i;spfa();int num=0;for(int j=1;j<=d;j++){num+=dist[c[j]];}res=min(res,num);}cout<<res<<endl;return 0;
}

NC17511:公交线路

//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 200010
int n,m,k,c[N],g,s,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int dist[N],vis[N],stop[N];
int to[N*2],head[N*2]={-1},ne[N*2],w[N*2];//这个因为是无向图;双向
int idx=0;
int p;//开始的地方:
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x];head[x]=idx++;}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[p]=0;vis[p]=1;queue<int>q;q.push(p);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){int i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}}
int main() {memset(head,-1,sizeof(head));cin>>n>>m>>s>>d;p=s;while(m--){cin>>x>>y>>z;add(x,y,z);add(y,x,z);}spfa();if(dist[d]==inf)cout<<0<<endl;else cout<<dist[d]<<endl;return 0;
}

NC14292:Travel

//对于N要进行适应性的更改,对于字段错误
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 200010
int n,m,k,q,g,d;
int x,y,z;
char ch;
string str;
vector<int>v[N];
int dist[N],vis[N];
int to[N*5],head[N*5]={-1},ne[N*5],w[N*5];//这个因为是无向图;双向
int idx=0;
int p;
void add(int x,int y,int z){to[idx]=y;w[idx]=z;ne[idx]=head[x];head[x]=idx++;}
void spfa(){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));dist[p]=0;vis[p]=1;queue<int>q;q.push(p);while(q.size()){x=q.front();q.pop();vis[x]=0;for(int j=head[x];j!=-1;j=ne[j]){int i=to[j];if(dist[i]>dist[x]+w[j]){dist[i]=dist[x]+w[j];if(vis[i]==0){q.push(i);vis[i]=1;}}}}}
int main() {memset(head,-1,sizeof(head));cin>>n>>m;for(int i=1;i<=n;i++){if(i==n){cin>>x;add(i,1,x);add(1,i,x);}else{cin>>x;add(i,i+1,x);add(i+1,i,x);}}for(int i=1;i<=m;i++){cin>>x>>y>>z;if(x==y)continue;add(x,y,z);add(y,x,z);}cin>>q;while(q--){cin>>x>>y;p=x;spfa();cout<<dist[y]<<endl;}return 0;
}///-------------------------------------------
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
using namespace std;
const int N=52501+10,M=22;
ll n,m,q,x,y;
ll p[N],dist[N][M<<1];
int d[N],h[N],tot,door[M<<1];
bool st[N];
struct node{int to,nxt,k;
}e[N*2];
void add(int u,int v,int w){e[++tot].to=v;e[tot].nxt=h[u];e[tot].k=w;h[u]=tot;
}
void dijkstra(int x){int s=door[x];dist[s][x]=0;priority_queue<PII,vector<PII>,greater<PII>> heap;heap.push({s,0});while(heap.size()){int u=heap.top().first;heap.pop();for(int i=h[u];i!=-1;i=e[i].nxt){int v=e[i].to;if(dist[v][x]>dist[u][x]+e[i].k){dist[v][x]=dist[u][x]+e[i].k;heap.push({v,dist[v][x]});}}}
}
int main(){cin>>n>>m;memset(h,-1,sizeof h);memset(dist,0x3f,sizeof dist);for(int i=1;i<=n;++i) cin>>d[i],p[i]=p[i-1]+d[i];for(int i=1;i<n;++i){add(i,(i+1),d[i]);add((i+1),i,d[i]);}add(1,n,d[n]),add(n,1,d[n]);int nd=0;for(ll i=1,u,v,w;i<=m;++i){cin>>u>>v>>w;add(u,v,w),add(v,u,w);door[++nd]=u,door[++nd]=v;}sort(door+1,door+1+nd);nd=unique(door+1,door+1+nd)-(door+1);for(int i=1;i<=nd;++i)dijkstra(i);cin>>q;while(q--){cin>>x>>y;ll len=abs(p[x-1]-p[y-1]);ll ans=min(len,p[n]-len);for(int i=1;i<=nd;++i)ans=min(ans,dist[x][i]+dist[y][i]);cout<<ans<<endl;}return 0;
}

相关文章:

【牛客网】

目录知识框架No.1 前缀和NC14556&#xff1a;数圈圈NC14600&#xff1a;珂朵莉与宇宙NC21195 &#xff1a;Kuangyeye and hamburgersNC19798&#xff1a;区间权值NC16730&#xff1a;runNC15035&#xff1a;送分了qaqNo.2 字符串&#xff1a;小知识点&#xff1a;基于KMP算法的…...

SpringBoot中的事务

事务 Springboot有3种技术方式来实现让加了Transactional的方法能使用数据库事务&#xff0c;分别是"动态代理(运行时织入)"、“编译期织入”和“类加载期织入”。这3种技术都是基于AOP(Aspect Oriented Programming&#xff0c;面向切面编程)思想。&#xff08;在网…...

Zookeeper客户端Curator5.2.0节点事件监听CuratorCache用法

Curator提供了三种Watcher&#xff1a; &#xff08;1&#xff09;NodeCache&#xff1a;监听指定的节点。 &#xff08;2&#xff09;PathChildrenCache&#xff1a;监听指定节点的子节点。 &#xff08;3&#xff09;TreeCache&#xff1a;监听指定节点和子节点及其子孙节点。…...

C++ using:软件设计中的面向对象编程技巧

C using:理解头文件与库的使用引言using声明a. 使用方法和语法b. 实际应用场景举例i. 避免命名冲突ii. 提高代码可读性c. 注意事项和潜在风险using指令a. 使用方法和语法b. 实际应用场景举例i. 将整个命名空间导入当前作用域ii. 代码组织和模块化using枚举a. C11的新特性b. 使用…...

修建灌木顺子日期

题目 有 N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晩会修剪一棵灌 木, 让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始, 每天向右修剪一棵灌木。当修剪了最右侧的灌木后, 她会调转方向, 下一天开 始向左修剪灌木。直到修剪了最左的灌木后再次调转方…...

深入学习JavaScript系列(七)——Promise async/await generator

本篇属于本系列第七篇 第一篇&#xff1a;#深入学习JavaScript系列&#xff08;一&#xff09;—— ES6中的JS执行上下文 第二篇&#xff1a;# 深入学习JavaScript系列&#xff08;二&#xff09;——作用域和作用域链 第三篇&#xff1a;# 深入学习JavaScript系列&#xff…...

Mybatis中的Map的使用和模糊查询的需求实现及其防SQL注入优化

文章目录一.Map的使用和模糊查询的需求实现及其防SQL注入优化1.1 Map的使用1.2 模糊查询的实现1.2.1 防SQL注入优化1.2.2 总结一.Map的使用和模糊查询的需求实现及其防SQL注入优化 1.1 Map的使用 替换之前的根据ID查询信息&#xff1a; 1.编写接口&#xff1a; User getUse…...

【redis】redis缓存更新策略

目录一、缓存更新策略二、主动更新策略三、Cache Aside Pattern3.1 删除缓存还是更新缓存?3.2 如何保证缓存与数据库的操作同时成功或失败&#xff1f;3.3 先操作缓存还是先操作数据库3.3.1 先删缓存再删库3.3.2 先删库再删缓存一、缓存更新策略 1.内存淘汰&#xff1a;不用自…...

LeetCode刷题--复制带随机指针的链表

复制带随机指针的链表1.题目2.解题思路3.完整代码1.题目 题目链接: https://leetcode.cn/problems/copy-list-with-random-pointer/ 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 …...

关于我的第一台电脑 华硕

2011年买的&#xff0c;第一台电脑是华硕 U36KI243SD 13.3英寸 白色 i5 1G独显 USB3.0 500G 当时花了5699&#xff0c;着实是一笔巨款&#xff0c;我同学看了一眼就说“我C&#xff0c;这本真好”。 买它主要还是因为好看。当时win7也才开始流行&#xff0c;感觉用上这个本&…...

【华为OD机试 2023最新 】 最大化控制资源成本(C++ 100%)

文章目录 题目描述输入描述输出描述备注用例题目解析C++题目描述 公司创新实验室正在研究如何最小化资源成本,最大化资源利用率,请你设计算法帮他们解决一个任务混部问题: 有taskNum项任务,每个任务有开始时间(startTime),结束时间(endTime),并行度(parallelism)…...

leetcode 有序数组的平方(977)

题目 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&#xff0c;数组变…...

文本三剑客之awk

文本三剑客之awkawk命令的简要处理流程awk命令的执行过程NR输出分割符和输入分割符案例awk命令引用shell变量awk的几个内置函数流控数组awk命令的简要处理流程 awk命令的执行过程 awk BEGIN{commands} pattern{commands} END{commands}files 执行BEGIN {commands}语句块中的语…...

RK3568平台开发系列讲解(驱动基础篇)IS_ERR函数的使用

🚀返回专栏总目录 文章目录 一、IS_ERR函数二、内核错误码沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 IS_ERR 函数的使用。 一、IS_ERR函数 对于任何一个指针来说,必然存在三种情况: 一种是合法指针一种是 NULL (也就是空指针)一种是错误指针(也就…...

特殊的类之注解

注解&#x1f699;注解的入门和作用以及原理示例注解的方法名就是属性名Retention的作用Target的作用注解的属性设置默认值天生我材必有用&#xff0c;千金散尽还复来。——唐代李白《将进酒》 在Java中&#xff0c;注解实际上是特殊类型的接口&#xff0c;当我们使用注解时&am…...

商业分享:盲盒电商开启电商新可能

盲盒&#xff0c;顾名思义&#xff0c;一个看不出里面装着什么东西的盒子。当你看不见盲盒里的商品时&#xff0c;你会思考盲盒里可能装着什么&#xff0c;它会诱发你的好奇心&#xff0c;而在好奇心的促使下&#xff0c;你会不由自主地买一个拆开来看&#xff0c;刚好大多数盲…...

【计算机架构】如何计算 CPU 时间

目录 0x00 响应时间和吞吐量&#xff08;Response Time and Throughput&#xff09; 0x01 相对性能&#xff08;Relative Performance&#xff09; 0x02 执行时间测量&#xff08;Measuring Execution Time&#xff09; 0x03 CPU 时钟&#xff08;Clocking&#xff09; 0x…...

银行数字化转型导师坚鹏:银行行长如何进行数字化转型

银行行长如何进行数字化转型 ——数字化转型背景下重塑银行行长核心竞争力 授课背景&#xff1a; 很多银行存在以下问题&#xff1a;银行行长不知道如何进行数字化转型&#xff1f;银行行长不清楚银行数字化能力模型的内涵&#xff1f;银行行长不知道如何通过数字化转型提…...

N32G45x学习笔记--- gpio引脚复用

关于gpio的引脚复用需要开启复用时钟 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);官方引脚复用: 芯片上电默认使能 SWD-JTAG 调试接口,调试接口被映射到 GPIO 端口上 禁止 JTAG 使能SWJ-DP /* 禁止 JTAG 使能SWJ-DP */GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_S…...

ArcGIS Pro中使用深度学习的高分辨率土地覆盖制图

本文非常详细的讲解了利用深度学习在高分辨率土地覆盖制图的应用&#xff0c;本文作者&#xff1a;Amin Tayyebi&#xff0c;文章从数据准备到训练U-Net模型等等细节都有讲解。本译文只是使用谷歌翻译而成。文章可能有错误语句及不通顺情况&#xff0c;所以仅供参考学习。有需要…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...