图论刷题
卡码网 98. 所有可达路径
使用邻接矩阵存储:
#include<iostream>
#include<vector>
using namespace std;vector<vector<int>>res;//收集符合条件的路径vector<int>path;//0节点到终点的路径//确定递归函数 参数和返回值void dfs(const vector<vector<int>>& graph,int x,int n){//确定终止条件if(x==n){res.push_back(path);return;}//确定单层递归逻辑for(int i=1;i<=n;i++){//寻找x节点指向的节点if(graph[x][i]==1){path.push_back(i);dfs(graph,i,n);path.pop_back();}}}
int main(){int n,m,s,t;//输入数据cin>>n>>m;vector<vector<int>>graph(n+1,vector<int>(n+1,0));while(m--){cin>>s>>t;graph[s][t]=1;}//遍历path.push_back(1);dfs(graph,1,n);//输出数据if(res.size()==0)cout<<-1<<endl;for(const vector<int>& pa:res){for(int i=0;i<pa.size()-1;i++){cout<<pa[i]<<' ';}cout<<pa[pa.size()-1]<<endl;}return 0;
}
使用邻接表存储:
#include<iostream>
#include<vector>
#include<list>
using namespace std;vector<vector<int>>res;//收集符合条件的路径vector<int>path;//0节点到终点的路径//确定递归函数 参数和返回值void dfs(const vector<list<int>>& graph,int x,int n){//确定终止条件if(x==n){res.push_back(path);return;}//确定单层递归逻辑for(int i:graph[x]){//寻找x节点指向的节点path.push_back(i);dfs(graph,i,n);path.pop_back();}}
int main(){int n,m,s,t;//输入数据cin>>n>>m;vector<list<int>>graph(n+1);while(m--){cin>>s>>t;graph[s].push_back(t);}//遍历path.push_back(1);dfs(graph,1,n);//输出数据if(res.size()==0)cout<<-1<<endl;for(const vector<int>& pa:res){for(int i=0;i<pa.size()-1;i++){cout<<pa[i]<<' ';}cout<<pa[pa.size()-1]<<endl;}return 0;
}
卡码网 99. 岛屿数量
dfs搜索:
#include<iostream>
#include<vector>
using namespace std;int dir[4][2]={0,1,1,0,0,-1,-1,0};//右下左上 四个方向
//确定递归函数参数和返回值
void dfs(const vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){//确定终止条件//if(visited[x][y]==true||grid[x][y]==0)return;//不能加这个终止,我在上一层已经把状态变为true,我就是要遍历这个点的四周的,你//给我终止了,破坏了我的遍历//确定单层递归逻辑for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size())continue;if(grid[nextx][nexty]==1&&visited[nextx][nexty]==false){visited[nextx][nexty]=true;dfs(grid,visited,nextx,nexty);//不需要回溯,就是要dfs遍历一遍把周围的陆地都标记一下}}
}
int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int x=0;x<n;x++){for(int y=0;y<m;y++){cin>>grid[x][y];}}vector<vector<bool>>visited(n,vector<bool>(m,false));//处理数据int res=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1&&visited[i][j]==false){res++;visited[i][j]=true;dfs(grid,visited,i,j);}}}cout<<res<<endl;return 0;
}
bfs搜索
#include<iostream>
#include<vector>
#include<queue>
using namespace std;int dir[4][2]={0,1,1,0,0,-1,-1,0};//右下左上 四个方向//确定递归函数参数和返回值
void bfs(const vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){//确定终止条件//确定单层递归逻辑queue<pair<int,int>>que;que.push({x,y});visited[x][y]=true;while(!que.empty()){pair<int,int>pa=que.front();que.pop();int curx=pa.first;int cury=pa.second;for(int i=0;i<4;i++){int nextx=curx+dir[i][0];int nexty=cury+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size())continue;if(grid[nextx][nexty]==1&&visited[nextx][nexty]==false){que.push({nextx,nexty});visited[nextx][nexty]=true;}}}}
int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int x=0;x<n;x++){for(int y=0;y<m;y++){cin>>grid[x][y];}}vector<vector<bool>>visited(n,vector<bool>(m,false));//处理数据int res=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1&&visited[i][j]==false){res++;bfs(grid,visited,i,j);}}}cout<<res<<endl;return 0;
}
分析:对于这道题,dfs与bfs的做法,dfs函数中还有对dfs函数本身的调用;bfs函数中没有对bfs函数本身的调用,bfs做法中,对一个点进行bfs函数,把这个点压入队列中,让后从队列中取出点,对点的四周进行遍历,如果符合条件,就把点压入队列中,让后函数一直持续从队列中取数进行遍历,直到队列中为空。
100. 岛屿的最大面积
dfs法一:(dfs函数处理下一个节点,不需要再写终止条件,因为终止条件包含在单层循环处理中)
#include<iostream>
#include<vector>
using namespace std;int dir[4][2]={0,1,1,0,0,-1,-1,0};
int count=0;
//dfs处理下一个节点
//确定递归函数参数和返回值
void dfs(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;if(visited[nextx][nexty]==false&&grid[nextx][nexty]==1){count++;visited[nextx][nexty]=true;dfs(grid,visited,nextx,nexty);}}
}int main(){//输入数据int res=0;int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}vector<vector<bool>>visited(n,vector<bool>(m,false));//处理数据for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1&&visited[i][j]==false){count=1;visited[i][j]=true;dfs(grid,visited,i,j);res=max(count,res);}}}cout<<res<<endl;return 0;
}
dfs法二(dfs处理当前节点,需要写终止条件)
#include<iostream>
#include<vector>
using namespace std;int dir[4][2]={0,1,1,0,0,-1,-1,0};
int count=0;
//dfs处理当前节点
//确定递归函数参数和返回值
void dfs(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){//确定终止条件if(grid[x][y]==0||visited[x][y]==true) return;//确定单层递归逻辑count++;visited[x][y]=true;for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;dfs(grid,visited,nextx,nexty);}
}int main(){//输入数据int res=0;int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}vector<vector<bool>>visited(n,vector<bool>(m,false));//处理数据for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1&&visited[i][j]==false){count=0;dfs(grid,visited,i,j);res=max(count,res);}}}cout<<res<<endl;return 0;
}
方法三:(bfs遍历)
#include<iostream>
#include<vector>
#include<queue>
using namespace std;int dir[4][2]={0,1,1,0,0,-1,-1,0};
int count=0;
//dfs处理当前节点
//确定递归函数参数和返回值
void bfs(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){//确定单层递归逻辑queue<pair<int,int>>que;que.push({x,y});count++;visited[x][y]=true;while(!que.empty()){pair<int,int>pa=que.front();que.pop();int xx=pa.first;int yy=pa.second;for(int i=0;i<4;i++){int nextx=xx+dir[i][0];int nexty=yy+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;if(grid[nextx][nexty]==1&&visited[nextx][nexty]==false){que.push({nextx,nexty});count++;visited[nextx][nexty]=true;}}}
}int main(){//输入数据int res=0;int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}vector<vector<bool>>visited(n,vector<bool>(m,false));//处理数据for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1&&visited[i][j]==false){count=0;bfs(grid,visited,i,j);res=max(count,res);}}}cout<<res<<endl;return 0;
}
101. 孤岛的总面积
用dfs遍历
#include<iostream>
#include<vector>
using namespace std;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
//确定递归函数参数和返回值
//该dfs是为了把靠边缘的岛屿变成海洋
void dfs(vector<vector<int>>& grid,int x,int y){//确定单层递归逻辑grid[x][y]=0;for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()){continue;}if(grid[nextx][nexty]==0) continue;dfs(grid,nextx,nexty);}}
int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}//处理数据//遍历挨着边缘的岛屿for(int i=0;i<n;i++){if(grid[i][0]==1) dfs(grid,i,0);if(grid[i][m-1]==1) dfs(grid,i,m-1);}for(int j=0;j<m;j++){if(grid[0][j]==1) dfs(grid,0,j);if(grid[n-1][j]==1) dfs(grid,n-1,j);}int res=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1)res++;}}cout<<res<<endl;return 0;
}
使用bfs遍历:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
//确定递归函数参数和返回值
//该bfs是为了把靠边缘的岛屿变成海洋
void bfs(vector<vector<int>>& grid,int x,int y){//确定单层递归逻辑grid[x][y]=0;queue<pair<int,int>>que;que.push({x,y});while(!que.empty()){pair<int,int>pa;pa=que.front();que.pop();int xx=pa.first;int yy=pa.second;for(int i=0;i<4;i++){int nextx=xx+dir[i][0];int nexty=yy+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()){continue;}if(grid[nextx][nexty]==0) continue;que.push({nextx,nexty});grid[nextx][nexty]=0;}}}
int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}//处理数据//遍历挨着边缘的岛屿for(int i=0;i<n;i++){if(grid[i][0]==1) bfs(grid,i,0);if(grid[i][m-1]==1) bfs(grid,i,m-1);}for(int j=0;j<m;j++){if(grid[0][j]==1) bfs(grid,0,j);if(grid[n-1][j]==1) bfs(grid,n-1,j);}int res=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1)res++;}}cout<<res<<endl;return 0;
}
102. 沉没孤岛
使用dfs遍历
#include<iostream>
#include<vector>
using namespace std;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
//确定递归函数参数和返回值
//该dfs是为了把靠边缘的岛屿用2标记,让后主函数中再遍历把2变成1,1变成0
void dfs(vector<vector<int>>& grid,int x,int y){//确定单层递归逻辑grid[x][y]=2;for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()){continue;}if(grid[nextx][nexty]==0||grid[nextx][nexty]==2) continue;dfs(grid,nextx,nexty);}}
int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}//处理数据//遍历挨着边缘的岛屿for(int i=0;i<n;i++){if(grid[i][0]==1) dfs(grid,i,0);if(grid[i][m-1]==1) dfs(grid,i,m-1);}for(int j=0;j<m;j++){if(grid[0][j]==1) dfs(grid,0,j);if(grid[n-1][j]==1) dfs(grid,n-1,j);}for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1) grid[i][j]=0;if(grid[i][j]==2) grid[i][j]=1;}}for(int i=0;i<n;i++){for(int j=0;j<m;j++){cout<<grid[i][j]<<' ';}cout<<endl;}return 0;
}
使用bfs遍历
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
//确定递归函数参数和返回值
//该bfs是为了把靠边缘的岛屿用2标记,让后主函数中再遍历把2变成1,1变成0
void bfs(vector<vector<int>>& grid,int x,int y){//确定单层递归逻辑grid[x][y]=2;queue<pair<int,int>>que;que.push({x,y});while(!que.empty()){pair<int,int>pa;pa=que.front();que.pop();int xx=pa.first;int yy=pa.second;for(int i=0;i<4;i++){int nextx=xx+dir[i][0];int nexty=yy+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()){continue;}if(grid[nextx][nexty]==0||grid[nextx][nexty]==2) continue;que.push({nextx,nexty});grid[nextx][nexty]=2;}}}
int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}//处理数据//遍历挨着边缘的岛屿for(int i=0;i<n;i++){if(grid[i][0]==1) bfs(grid,i,0);if(grid[i][m-1]==1) bfs(grid,i,m-1);}for(int j=0;j<m;j++){if(grid[0][j]==1) bfs(grid,0,j);if(grid[n-1][j]==1) bfs(grid,n-1,j);}for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1)grid[i][j]=0;if(grid[i][j]==2) grid[i][j]=1;}}for(int i=0;i<n;i++){for(int j=0;j<m;j++){cout<<grid[i][j]<<' ';}cout<<endl;}return 0;
}
103. 水流问题
#include<iostream>
#include<vector>
using namespace std;int dir[4][2]={0,1,1,0,0,-1,-1,0};//确定递归函数 参数
//该dfs遍历,是对当前节点进行处理。从边缘逆流遍历,标记能到达边缘的坐标
void dfs(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y){//确定终止条件if(visited[x][y]==true) return;//确定单层递归逻辑visited[x][y]=true;for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()){continue;}if(grid[x][y]>grid[nextx][nexty]) continue;dfs(grid,visited,nextx,nexty);}
}int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}//处理数据vector<vector<bool>>firstBorder(n,vector<bool>(m,false));vector<vector<bool>>secondBorder(n,vector<bool>(m,false));//从边缘进行dfs遍历,标记目的单元格for(int i=0;i<n;i++){dfs(grid,firstBorder,i,0);//左侧dfs(grid,secondBorder,i,m-1);//右侧}for(int j=0;j<m;j++){dfs(grid,firstBorder,0,j);//上侧dfs(grid,secondBorder,n-1,j);//下侧}for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(firstBorder[i][j]&&secondBorder[i][j]) cout<<i<<' '<<j<<endl;}}return 0;
}
104. 建造最大岛屿
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
using namespace std;
int dir[4][2]={0,1,1,0,-1,0,0,-1};
int count;
//确定递归函数参数
//该dfs是将每个岛屿染成不同的颜色,并计算每个岛屿的面积大小
void dfs(vector<vector<int>>& grid,vector<vector<bool>>& visited,int x,int y,int mark){//确定终止条件if(grid[x][y]==0||visited[x][y]) return;//确定单层递归逻辑visited[x][y]=true;count++;grid[x][y]=mark;for(int i=0;i<4;i++){int nextx=x+dir[i][0];int nexty=y+dir[i][1];if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;dfs(grid,visited,nextx,nexty,mark);}
}int main(){//输入数据int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}vector<vector<bool>>visited(n,vector<bool>(m,false));//处理数据unordered_map<int,int> gridNum;//记录每个岛屿的面积int mark=2;//记录每个岛屿的编号bool isAllGrid=true;//标记是否整个地图都是陆地for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==0)isAllGrid=false;if(visited[i][j]==false&&grid[i][j]==1){count=0;dfs(grid,visited,i,j,mark);gridNum[mark]=count;mark++;}}}if(isAllGrid){cout<<n*m<<endl;return 0;}//根据添加陆地的位置,计算周边岛屿面积之和int res=0;//记录最后结果unordered_set<int>visitedGrid;//标记访问过的岛屿for(int i=0;i<n;i++){for(int j=0;j<m;j++){count=1;//记录连接之后的岛屿数量visitedGrid.clear();//每次使用时清空if(grid[i][j]==0){for(int k=0;k<4;k++){int nearx=i+dir[k][0];int neary=j+dir[k][1];if(nearx<0||nearx>=grid.size()||neary<0||neary>=grid[0].size()){continue;}if(visitedGrid.count(grid[nearx][neary]))continue;//添加过的岛屿不要重复添加count+=gridNum[grid[nearx][neary]];visitedGrid.insert(grid[nearx][neary]);}}res=max(res,count);}}cout<<res<<endl;return 0;
}
思路真的感觉很难想,而且代码很难实现。不过这道题应该还是要练图论的遍历,用的dfs遍历,感觉对图论的遍历更加掌握了。
110. 字符串接龙
#include<iostream>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<queue>
#include<string>
using namespace std;
int main(){//输入数据int n;cin>>n;string str,beginStr,endStr;cin>>beginStr>>endStr;unordered_set<string> strSet;for(int i=0;i<n;i++){cin>>str;strSet.insert(str);}//处理数据//转换的字符串之间只相差一个字符,字符串之间的连接形成了一个无向图,//遍历无向图,找到最短路径,使用广搜。//尝试替换每一个字符,如果在set字典中找到,并且没有没遍历过,//就可以加入que中,加入map中保存queue<string>que;que.push(beginStr);//初始化队列unordered_map<string,int>strMap;//map用来记录遍历长度,验证是否遍历过strMap.insert(pair<string,int>(beginStr,1));//初始化mapwhile(!que.empty()){string word=que.front();que.pop();int path=strMap[word];//轮流替换每个字符for(int i=0;i<word.size();i++){string newword=word;//不能在原本的字符上直接替换//尝试替换26个字符for(int j=0;j<26;j++){newword[i]=j+'a';if(newword==endStr){cout<<path+1<<endl;return 0;}if(strSet.find(newword)!=strSet.end()&&strMap.find(newword)==strMap.end()){que.push(newword);strMap.insert(pair<string,int>(newword,path+1));}}}}cout<<0<<endl;//没找到
}
105. 有向图的完全可达性
#include<iostream>
#include<list>
#include<vector>
using namespace std;//确定递归函数参数 使用dfs遍历
void dfs(const vector<list<int>>& grid,vector<bool>& visited,int key){//dfs处理当前节点if(visited[key]) return;//确定单层递归逻辑visited[key]=true;list<int>keys=grid[key];for(int key : keys){dfs(grid,visited,key);}
}int main(){//输入数据int n,k,s,t;cin>>n>>k;//使用邻接表保存图vector<list<int>> grid(n+1);while(k--){cin>>s>>t;grid[s].push_back(t);}//处理数据vector<bool> visited(n+1,false);dfs(grid,visited,1);for(int i=1;i<=n;i++){if(visited[i]==false) {cout<<-1<<endl;return 0;}}cout<<1<<endl;return 0;
}
dfs遍历 细微差别
#include<iostream>
#include<list>
#include<vector>
using namespace std;//确定递归函数参数 使用dfs遍历
void dfs(const vector<list<int>>& grid,vector<bool>& visited,int key){//dfs处理下一个节点//确定单层递归逻辑list<int>keys=grid[key];for(int key : keys){if(visited[key])continue;visited[key]=true;dfs(grid,visited,key);}
}int main(){//输入数据int n,k,s,t;cin>>n>>k;//使用邻接表保存图vector<list<int>> grid(n+1);while(k--){cin>>s>>t;grid[s].push_back(t);}//处理数据vector<bool> visited(n+1,false);visited[1]=true;dfs(grid,visited,1);for(int i=1;i<=n;i++){if(visited[i]==false) {cout<<-1<<endl;return 0;}}cout<<1<<endl;return 0;
}
通过bfs遍历
#include<iostream>
#include<list>
#include<vector>
#include<queue>
using namespace std;//确定递归函数参数 使用bfs遍历
void bfs(const vector<list<int>>& grid,vector<bool>& visited,int key){//确定单层递归逻辑queue<int>que;que.push(key);while(!que.empty()){int cur=que.front();que.pop();list<int>keys=grid[cur];for(int key:keys){if(visited[key]) continue;visited[key]=true;que.push(key);}}
}int main(){//输入数据int n,k,s,t;cin>>n>>k;//使用邻接表保存图vector<list<int>> grid(n+1);while(k--){cin>>s>>t;grid[s].push_back(t);}//处理数据vector<bool> visited(n+1,false);visited[1]=true;bfs(grid,visited,1);for(int i=1;i<=n;i++){if(visited[i]==false) {cout<<-1<<endl;return 0;}}cout<<1<<endl;return 0;
}
106. 岛屿的周长
#include<iostream>
#include<vector>
using namespace std;
int dir[4][2]={0,1,1,0,-1,0,0,-1};
int main(){int n,m;cin>>n>>m;vector<vector<int>>grid(n,vector<int>(m,0));for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>grid[i][j];}}int res=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]==1){for(int k=0;k<4;k++){int x=i+dir[k][0];int y=j+dir[k][1];if(x<0||x>=n||y<0||y>=m||grid[x][y]==0)res++;}}}}cout<<res<<endl;return 0;
}
107. 寻找存在的路径
#include<iostream>
#include<vector>
using namespace std;
//确定节点数量
int n=105;
//根节点数组
vector<int>father(n,0);
//并查集初始化
void init(){for(int i=0;i<n;i++){father[i]=i;}
}
//并查集里寻根过程
int find(int u){return father[u]==u?u:father[u]=find(father[u]);
}
//判断u和v是否同一个根
bool isSame(int u,int v){u=find(u);v=find(v);return u==v;
}
//将v->u加入到并查集中
void ioin(int u,int v){u=find(u);v=find(v);if(u==v) return ;father[v]=u;
}
int main(){int m,s,t,source,destination;cin>>n>>m;init();for(int i=0;i<m;i++){cin>>s>>t;ioin(s,t);}cin>>source>>destination;if(isSame(source,destination))cout<<1<<endl;else cout<<0<<endl;return 0;
}
108. 冗余连接
#include<iostream>
#include<vector>
using namespace std;
//确定节点个数
int n=1005;
vector<int>father(n,0);
//初始化并查集
void init(){for(int i=0;i<n;i++){father[i]=i;}
}
//并查集中寻根
int find(int u){return u==father[u]?u:father[u]=find(father[u]);
}
//判断是否在一个集合里
bool isSame(int u,int v){u=find(u);v=find(v);return u==v;
}
//将v->u加入到并查集中
void join(int u,int v){u=find(u);v=find(v);if(u==v)return;father[v]=u;
}
int main(){int s,t;cin>>n;init();for(int i=0;i<n;i++){cin>>s>>t;if(isSame(s,t)){cout<<s<<' '<<t<<endl;return 0;}else join(s,t);}
}
109. 冗余连接II
#include<iostream>
#include<vector>
using namespace std;int n=1005;
vector<int>father(n,0);
//并查集初始化
void init(){for(int i=0;i<n;i++){father[i]=i;}
}
//并查集中查根
int find(int u){return u==father[u]?u:father[u]=find(father[u]);
}
//判断并查集中是否同根
bool isSame(int u,int v){u=find(u);v=find(v);return u==v;
}
//将v->u加入并查集中
void join(int u,int v){u=find(u);v=find(v);if(u==v)return;father[v]=u;
}
bool isTreeAfterRemoveEdge(vector<vector<int>>& edges,int deleedge){//删除某边,利用并查集看是否构成有向树。或者删除另一条边。init();for(int i=0;i<n;i++){if(i==deleedge) continue;if(isSame(edges[i][0],edges[i][1])){return false;}join(edges[i][0],edges[i][1]);}return true;}
void getRemoveEdge(vector<vector<int>>& edges){//依次将各个边加入并查集中,同时看是否构成环init();for(int i=0;i<n;i++){if(isSame(edges[i][0],edges[i][1])) {cout<<edges[i][0]<<' '<<edges[i][1]<<endl;return;}join(edges[i][0],edges[i][1]);}}
int main(){//输入数据int s,t;cin>>n;vector<vector<int>>edges;//保存有向边vector<int>inDegree(n,0);for(int i=0;i<n;i++){cin>>s>>t;inDegree[t]++;//入度加一edges.push_back({s,t});}//处理数据 考虑三种情况//寻找有没有入度为2的,如果有,找到对应的两条边,删除某边,利用isTreeAfterRemoveEdge函数//为了保证最先删除的是最后输入的边,将两条边提取出来,按一定顺序尝试删除//情况三,入度没有2的,则是构成了单向环,利用getMoveEdge函数vector<int>vec;//记录指向入度为2的点//寻找度为2的for(int i=n-1;i>=0;i--){if(inDegree[edges[i][1]]==2){vec.push_back(i);}}//情况一,二if(vec.size()==2){if(isTreeAfterRemoveEdge(edges,vec[0])){cout<<edges[vec[0]][0]<<' '<<edges[vec[0]][1]<<endl;}else cout<<edges[vec[1]][0]<<' '<<edges[vec[1]][1]<<endl;return 0;}//情况三getRemoveEdge(edges);}
53. 寻宝(第七期模拟笔试)
最小生成树 prim算法
#include<iostream>
#include<vector>
#include<climits>
using namespace std;int main(){int v,e,s,p,t;cin>>v>>e;vector<vector<int>>grid(v+1,vector<int>(v+1,10001));//存储图for(int i=1;i<=e;i++){cin>>s>>p>>t;grid[s][p]=t;grid[p][s]=t;//存储边及权值}vector<bool>isIntree(v+1,false);//是否在树里//所有节点到最小生成树的最小距离vector<int>minDist(v+1,10001);//需要执行n-1次三部曲,将边加入到最小生成树中for(int i=1;i<v;i++){int cur=-1;//要加入最小生成树的节点int minVal=INT_MAX;//非最小生成树节点到树的最短距离//prim第一步 选距离最小生成树最近的节点//条件:1.不在最小生成树里,//2.距离最小生成树最近的节点for(int j=1;j<=v;j++){if(!isIntree[j]&&minDist[j]<minVal){cur=j;minVal=minDist[j];}}//prim第二步 节点加入树isIntree[cur]=true;//rim第三步 更新非树节点到树的最小距离//只需要更新与新添加到树中节点相关的节点for(int j=1;j<=v;j++){if(!isIntree[j]&&grid[cur][j]<minDist[j]){minDist[j]=grid[cur][j];}}}int res=0;for(int i=2;i<=v;i++){res+=minDist[i];}cout<<res<<endl;return 0;
}
53. 寻宝(第七期模拟笔试)
最小生成树 kruskal算法
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;int n=10001;//节点数量
vector<int> father(n,0);
//初始化并查集
void init(){for(int i=1;i<n;i++){father[i]=i;}
}
//在并查集中查找根
int find(int u){return u==father[u]?u:father[u]=find(father[u]);
}
//判断是否在同一集合中
bool isSame(int u,int v){u=find(u);v=find(v);return u==v;
}
//将v->u加入到并查集中
void join(int u,int v){u=find(u);v=find(v);if(u==v)return;father[v]=u;
}struct edge{int l,r,val;
};
int main(){//输入数据int v,e,r,s,t;cin>>v>>e;vector<edge>edges(e+1);for(int i=1;i<=e;i++){cin>>r>>s>>t;edges.push_back({r,s,t});}//处理数据 //为edges排序,接着遍历,如果不构成环,就把边加入到并查集中,//同时累加权值int res_val=0;init();sort(edges.begin(),edges.end(),[](const edge& a,const edge& b){return a.val<b.val;});for(edge eg:edges){int i=find(eg.l);int j=find(eg.r);if(i!=j){res_val+=eg.val;join(i,j);}}cout<<res_val<<endl;return 0;
}
117. 软件构建
#include<iostream>
#include<vector>
#include<unordered_map>
#include<queue>
using namespace std;int main(){//输入数据int n,m,s,t;cin>>n>>m;unordered_map<int,vector<int>>umap(n);//记录文件间依赖关系vector<int>inDegree(n,0);for(int i=0;i<m;i++){cin>>s>>t;//先处理s再处理tumap[s].push_back(t);inDegree[t]++;//t的入度+1}//处理数据//1.找到入度为0的点,2.让其后缀节点入度减一。重复这两点queue<int>que;for(int i=0;i<n;i++){if(inDegree[i]==0) que.push(i);}vector<int>res;//记录处理顺序结果while(!que.empty()){int cur=que.front();que.pop();res.push_back(cur);vector<int>files;//保存入度为0节点的后缀节点files=umap[cur];for(int i=0;i<files.size();i++){inDegree[files[i]]-=1;if(inDegree[files[i]]==0)que.push(files[i]);}}if(res.size()==n){for(int i=0;i<n-1;i++){cout<<res[i]<<' ';}cout<<res[n-1]<<endl;}else cout<<-1<<endl;return 0;
}
47. 参加科学大会(第六期模拟笔试)
有向图中最短路径 dijkstra 算法朴素版
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
//有向图中求最短路径。三部曲做题法
//数据的存储:二维数组存有向边及权值;visited数组;minDist数组:(保存各节点到源点的最短距离)
//第一步:寻找距离源点最近的节点
//第二步:更新节点为已访问
//第三步:更新未访问节点到源点的最短距离
int main(){//输入数据int n,m,s,e,v;cin>>n>>m;vector<vector<int>>grid(n+1,vector<int>(n+1,INT_MAX));for(int i=1;i<=m;i++){cin>>s>>e>>v;grid[s][e]=v;}vector<bool>visited(n+1,false);//标记节点是否被访问vector<int>minDist(n+1,INT_MAX);////处理数据//需要循环处理三步曲n次,minDist[1]=0;for(int i=1;i<=n;i++){//第一步int cur=1;int minval=INT_MAX;for(int j=1;j<=n;j++){if(!visited[j]&&minDist[j]<minval){minval=minDist[j];cur=j;}}//第二步visited[cur]=true;//第三步//只需要更新cur连接的节点即可for(int j=1;j<=n;j++){if(!visited[j]&&grid[cur][j]!=INT_MAX&&minDist[cur]+grid[cur][j]<minDist[j]){minDist[j]=minDist[cur]+grid[cur][j]; }}}//输出数据if(minDist[n]==INT_MAX) {cout<<-1<<endl;}else {cout<<minDist[n]<<endl;}return 0;
}
47. 参加科学大会(第六期模拟笔试)
有向图中最短路径 dijkstra 算法堆优化版
#include<iostream>
#include<vector>
#include<queue>
#include<climits>
#include<list>
using namespace std;
//该方法也符合三部曲,朴素版是通过遍历n次(节点个数)三部曲,每次将一个节点加入集合中
//堆优化版是用小顶堆对边进行排序,每次选择最短的边,和kruskal思想相似
//数据准备:visited数组,minDist数组,grid数组+邻接表,优先队列
//第一步:取出小顶堆堆顶数据,(堆自动排序了)
//第二步:标记节点已访问
//第三步:更新cur节点链接的节点到源点的最短距离,加入优先队列中//构造一个结构体表示邻接表
struct Edge{int to;//临间顶点int val;//边的权重Edge(int t,int w):to(t),val(w){}//构造函数
};
//小顶堆
class mycomparison{
public:
//操作符重载函数bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){return lhs.second>rhs.second;//注意是大于,我也不知道为啥}
};int main(){//输入数据int n,m,s,e,v;cin>>n>>m;vector<list<Edge>>grid(n+1);for(int i=0;i<m;i++){cin>>s>>e>>v;grid[s].push_back(Edge(e,v));}vector<bool>visited(n+1,false);vector<int>minDist(n+1,INT_MAX);//pair<int,int> 表示<节点,节点到源点的权值>priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparison> pq;//处理数据pq.push(pair<int,int>(1,0));minDist[1]=0;//在队列不为空条件下进行三部曲的重复while(!pq.empty()){//第一步pair<int,int>cur=pq.top();pq.pop();//第二步visited[cur.first]=true;//第三步for(Edge edge:grid[cur.first]){if(!visited[edge.to]&&minDist[cur.first]+edge.val<minDist[edge.to]){minDist[edge.to]=minDist[cur.first]+edge.val;pq.push(pair<int,int>(edge.to,minDist[edge.to]));}}}if(minDist[n]==INT_MAX) cout<<-1<<endl;else cout<<minDist[n]<<endl;
}
dijkstra算法 不能用于权值有负数的情况
94. 城市间货物运输 I
Bellman_ford 算法
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
//对于权值有负值的求单项图的最短路径问题
//松弛n-1次(n个节点)
//每次松弛遍历单向边,更新终点到源点的最短距离
int main(){//输入数据int n,m,s,t,v;cin>>n>>m;vector<vector<int>>grid;for(int i=0;i<m;i++){cin>>s>>t>>v;grid.push_back({s,t,v});}//处理数据vector<int>minDist(n+1,INT_MAX);minDist[1]=0;for(int i=1;i<n;i++){for(vector<int> &vec:grid){//加&可以避免循环时复制vector数组而产生的时间和空间开销int from=vec[0];int to=vec[1];int val=vec[2];if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+val){minDist[to]=minDist[from]+val;}}}if(minDist[n]==INT_MAX) cout<<"unconnected"<<endl;else cout<<minDist[n]<<endl;return 0;
}
Bellman_ford 算法优化版本
#include<iostream>
#include<vector>
#include<list>
#include<climits>
#include<queue>
using namespace std;
//对bellman_ford 算法 进行优化,
//使用isInQueue数组,queue队列,减少无效次数的松弛
//构建结构体
struct Edge{int to;int val;Edge(int k,int w):to(k),val(w){}//构造函数
};
int main(){//输入数据int n,m,s,t,v;cin>>n>>m;vector<list<Edge>>grid(n+1);for(int i=0;i<m;i++){cin>>s>>t>>v;grid[s].push_back(Edge(t,v));}//处理数据vector<int>minDist(n+1,INT_MAX);vector<bool>isInQueue(n+1,false);minDist[1]=0;queue<int>que;que.push(1);isInQueue[1]=true;//进行松弛while(!que.empty()){int node=que.front();que.pop();isInQueue[node]=false;for(Edge &edge:grid[node]){int from=node;int to=edge.to;int val=edge.val;if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+val){minDist[to]=minDist[from]+val;if(!isInQueue[to]) {que.push(to);isInQueue[to]=true;}}}}if(minDist[n]==INT_MAX) cout<<"unconnected"<<endl;else cout<<minDist[n]<<endl;return 0;
}
95. 城市间货物运输 II
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
//本题存在负权回路的情况,正常只需要松弛n-1次就可以找到所有节点到源点的最短距离
//那么再多松弛一次,看minDist数组是否变化,有变化则存在负权回路
int main(){//输入数据int n,m,s,t,v;cin>>n>>m;vector<vector<int>>grid;for(int i=0;i<m;i++){cin>>s>>t>>v;grid.push_back({s,t,v});}//处理数据vector<int>minDist(n+1,INT_MAX);minDist[1]=0;bool fact=false;//进行n次松弛for(int i=1;i<=n;i++){for(vector<int>& vec:grid){int from=vec[0];int to=vec[1];int val=vec[2];if(i<n){if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+val)minDist[to]=minDist[from]+val;}else {if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+val)fact=true;}}}if(fact) cout<<"circle"<<endl;else {if(minDist[n]==INT_MAX) cout<<"unconnected"<<endl;else cout<<minDist[n]<<endl;}return 0;
}
SPFA法
#include<iostream>
#include<vector>
#include<list>
#include<climits>
#include<queue>
using namespace std;
//对bellman_ford 算法 进行优化,
//使用isInQueue数组,queue队列,减少无效次数的松弛
//构建结构体
struct Edge{int to;int val;Edge(int k,int w):to(k),val(w){}//构造函数
};
int main(){//输入数据int n,m,s,t,v;cin>>n>>m;vector<list<Edge>>grid(n+1);for(int i=0;i<m;i++){cin>>s>>t>>v;grid[s].push_back(Edge(t,v));}//处理数据vector<int>minDist(n+1,INT_MAX);vector<bool>isInQueue(n+1,false);vector<int>count(n+1,0);//记录节点加入队列的次数minDist[1]=0;queue<int>que;que.push(1);count[1]=1;bool fact=false;//进行松弛while(!que.empty()){int node=que.front();que.pop();for(Edge &edge:grid[node]){int from=node;int to=edge.to;int val=edge.val;if(minDist[from]!=INT_MAX&&minDist[to]>minDist[from]+val){minDist[to]=minDist[from]+val;if(!isInQueue[to]) {que.push(to);count[to]++;if(count[to]==n){fact=true;while(!que.empty())que.pop();break;}}}}}if(fact)cout<<"circle"<<endl;else if(minDist[n]==INT_MAX) cout<<"unconnected"<<endl;else cout<<minDist[n]<<endl;return 0;
}
96. 城市间货物运输 III
最多经过k个城市,从城市A到城市B的最短路径
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
//对所有边松弛n次,相当于计算起点到达与起点n条边相连的节点的最短距离
//最多经过k个城市,那么要到达与起点k+1个边相连的终点,松弛k+1次
//但是,要注意负权回路,更新minDist数组时,要看上一次松弛的from点的mindDise
int main(){//输入数据int n,m,s,t,v,src,dst,k;cin>>n>>m;vector<vector<int>>grid;for(int i=0;i<m;i++){cin>>s>>t>>v;grid.push_back({s,t,v});}cin>>src>>dst>>k;//处理数据vector<int>minDist(n+1,INT_MAX);vector<int>copy(n+1,INT_MAX);minDist[src]=0;//开始松弛for(int i=1;i<=k+1;i++){copy=minDist;for(vector<int>& vec:grid){int from=vec[0];int to=vec[1];int val=vec[2];if(copy[from]!=INT_MAX&&minDist[to]>copy[from]+val){minDist[to]=copy[from]+val;}}}if(minDist[dst]==INT_MAX) cout<<"unreachable"<<endl;else cout<<minDist[dst]<<endl;return 0;
}
97. 小明逛公园
Floyd算法
#include<iostream>
#include<vector>
using namespace std;int main(){//输入数据int n,m,u,v,w;cin>>n>>m;vector<vector<vector<int>>>dp(n+1,vector<vector<int>>(n+1,vector<int>(n+1,10005)));for(int i=0;i<m;i++){cin>>u>>v>>w;dp[u][v][0]=w;dp[v][u][0]=w;}//Floyd算法for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dp[i][j][k]=min(dp[i][j][k-1],dp[i][k][k-1]+dp[k][j][k-1]);}}}int q,start,end;cin>>q;while(q--){cin>>start>>end;if(dp[start][end][n]==10005) cout<<-1<<endl;else cout<<dp[start][end][n]<<endl;}return 0;
}
127. 骑士的攻击
#include<iostream>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;//A*算法 实际上是光搜的改良版
//光搜便利了太多多余的节点,可以加入一个启发式函数,引导算法向目标位置遍历
//通过对队列中的节点进行排序,让离目标最近的先出来。
//F=G+H。F是从起点到终点需要的距离。G是从起点到目前所遍历的节点经过的距离
//H是从目前节点到终点所需要的距离
//计算距离使用欧拉距离公式d=sqrt((x1-x2)^2+(y1-y2)^2)
int dir[8][2]={-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2,-2,-1};
int b1,b2;
int moves[1001][1001];//棋盘,同时记录路径长度struct Knight{int x,y;int g,h,f;bool operator <(const Knight & k) const {return k.f<f;}
};int Heuristic(const Knight &k){return (k.x-b1)*(k.x-b1)+(k.y-b2)*(k.y-b2);
}
priority_queue<Knight>que;
void astart(const Knight &k){Knight cur,next;que.push(k);while(!que.empty()){cur=que.top();que.pop();if(cur.x==b1&&cur.y==b2) break;for(int i=0;i<8;i++){//向八个方向遍历next.x=cur.x+dir[i][0];next.y=cur.y+dir[i][1];//排除掉不符合规定的情况if(next.x<1||next.x>1000||next.y<1||next.y>1000) continue;if(!moves[next.x][next.y]){//更新路径长度moves[next.x][next.y]=moves[cur.x][cur.y]+1;//开始计算f,g,hnext.g=cur.g+5;//没有开根号,为了提高精度next.h=Heuristic(next);next.f=next.g+next.h;que.push(next);}}}
}int main(){int n,a1,a2;cin>>n;while(n--){cin>>a1>>a2>>b1>>b2;memset(moves,0,sizeof(moves));//设置一块内存的值,//sizeof获取字节数Knight start;start.x=a1;start.y=a2;start.g=0;start.h=Heuristic(start);start.f=start.g+start.h;astart(start);while(!que.empty()) que.pop();cout<<moves[b1][b2]<<endl;}return 0;
}
相关文章:

图论刷题
卡码网 98. 所有可达路径 使用邻接矩阵存储: #include<iostream> #include<vector> using namespace std;vector<vector<int>>res;//收集符合条件的路径vector<int>path;//0节点到终点的路径//确定递归函数 参数和返回值void dfs(c…...

ICM20948 DMP代码详解(85)
接前一篇文章:ICM20948 DMP代码详解(84) 上一回解析了inv_icm20948_ctrl_enable_sensor函数的大部分代码,只剩下一行代码没有解析。为了便于理解和回顾,再次贴出inv_icm20948_ctrl_enable_sensor函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Data…...

深入解析:Linux tcpdump命令在网络流量分析中的实战应用
tcpdump是一个强大的命令行工具,用于捕获和分析TCP、UDP、ICMP等协议的网络流量。 功能与用途 捕获网络流量:tcpdump可以捕获和显示来自本地计算机或通过网络传输的数据包,提供有关数据包的详细信息,如源和目的IP地址、端口号、…...

Java集合常见知识总结(上)
Java 集合概览 Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于Collection 接口,下面又有三个主要的…...

【算法】力扣:K个一组反转链表
前置知识 数据结构-链表反转部分链表算法题的手写栈使用 难度: 初阶:使用容器, 难度中等。进阶:纯coding修改指针 ,难度中等,虽然leetcode是困难题。不过更加注重细节。 题目:反转 k 组中的…...

Matlab报错——错误使用 vertcat
错误提示: 原因: 这个错误表明 segment_lengths 的维度和 0 不一致。在 MATLAB 中,有时,diff 函数的输出可能是行向量,而segment_lengths 应该是一个列向量才能与 0 正确连接。 解决方法: 使用转置操作 …...

【如何获取股票数据10】Python、Java等多种主流语言实例演示获取股票行情api接口之沪深A股历史分时KDJ数据获取实例演示及接口API说明文档
最近一两年内,股票量化分析逐渐成为热门话题。而从事这一领域工作的第一步,就是获取全面且准确的股票数据。因为无论是实时交易数据、历史交易记录、财务数据还是基本面信息,这些数据都是我们进行量化分析时不可或缺的宝贵资源。我们的主要任…...

进入 Searing-66 火焰星球:第一周游戏指南
Alpha 第四季已开启,穿越火焰星球 Searing-66,带你开启火热征程。准备好勇闯炙热的沙漠,那里有无情的高温和无情的挑战在等待着你。从高风险的烹饪对决到炙热的冒险,Searing-66 将把你的耐力推向极限。带上充足的水,天…...

考研论坛设计小程序ssm+论文源码调试讲解
2相关技术 2.1微信小程序 小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。尤其拥抱微信生态圈,让微信小程序更加的如虎添翼,发展迅猛。 2.2 MYSQL数据…...

JAVA笔记 | EasyExcel创建带有简单下拉框的导入模板
目录 前文 业务需求 具体代码 新增Handler 控制层 前文 SpringBoot笔记 | EasyExcel导入导出及基于模板导出_easyexcel模板导出-CSDN博客 业务需求 需要一个导出模板。一个列需要填写固定的值,或者方便用户填写。 自己需求,几个固定的字段对应固…...

【含开题报告+文档+PPT+源码】贫困儿童一对一扶贫帮扶系统设计与实现
开题报告 根据《中华人民共和国慈善法》第五十八条规定,慈善组织确定慈善受益人,应当坚持公开、公平、公正的原则,不得指定慈善组织管理人员的利害关系人作为受益人[2]。以上所列举的平台基本没有做到公开、公平、公正的原则,例如…...

多系统萎缩不慌张,这些维生素是你的“隐形盾牌”!️
在这个快节奏的时代,健康成为了我们最宝贵的财富。而对于多系统萎缩(MSA)的患者来说,合理的营养补充更是维护身体机能、提升生活质量的关键一步。今天,就让我们一起揭秘那些能够成为多系统萎缩患者“守护神”的维生素吧…...

IGFBP7:免疫治疗新靶点
前 言 胰岛素样生长因子结合蛋白7(IGFBP7)是胰岛素超家族的生长促进肽成员,可与胰岛素和IGF结合,调控细胞生长和分化。IGFBP7在不同的肿瘤类型中表现出抑制或促进肿瘤生长的“自相矛盾”活性。研究发现IGFBP7可增强治疗性单克隆…...

深度学习模型的架构与应用:技术解析与未来展望
1. 引言 深度学习(Deep Learning)模型是当代人工智能的核心技术之一,广泛应用于语音识别、计算机视觉、自然语言处理、推荐系统等众多领域。深度学习通过构建多层神经网络,能够自动从大规模数据中学习复杂的特征和模式,其应用成果不仅推动了技术的飞跃,也带来了智能化产…...

机器学习——主要分类
前言: 机器学习是人工智能的重要分支之一,它通过分析数据来构建模型,并通过这些模型进行预测、分类或决策。随着数据量的迅速增长,机器学习在多个领域展现出巨大的应用潜力,推动了科技的进步。根据学习方式和数据的使用…...

Java密封类(Sealed Classes)增强详解
Java密封类(Sealed Classes)增强详解 Java 17引入了一个重要的新特性——密封类(Sealed Classes),这一特性旨在增强Java编程语言的能力,提供了一种机制来限制哪些类可以继承一个给定的类或者实现一个给定的…...

鸿蒙如何自动生成二维码?QRCode组件
QRCode 用于显示单个二维码的组件。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 二维码组件的像素点数量与内容有关,当组件尺寸过小时,可能出现无法展示内容的情况&…...

【分布式知识】MapReduce详细介绍
文章目录 MapReduce概述1. MapReduce编程模型Map阶段Reduce阶段 2. Shuffle和Sort阶段3. MapReduce作业的执行流程4. MapReduce的优化和特性5. MapReduce的配置和调优 MapReduce局限性相关文献 MapReduce概述 MapReduce是一个分布式计算框架,它允许用户编写可以在大…...

JAVA八股
快速失败(fail-fast) 设计的目的是为了避免在遍历时对集合进行并发修改,从而引发潜在的不可预料的错误。 通过迭代器遍历集合时修改集合: 如果你使用Iterator遍历集合,然后直接使用集合的修改方法(如add(…...

关于武汉芯景科技有限公司的限流开关芯片XJ6288开发指南(兼容SY6288)
一、芯片引脚介绍 1.芯片引脚 二、系统结构图 三、功能描述 1.EN引脚控制IN和OUT引脚的通断 2.OCB引脚指示状态 3.过流自动断开...

指令:计算机的语言(五)
2.9 人机交互 ASCII与二进制 对应表略 字节转移指令 lbu:加载无符号字节,从内存中加载1个字节,放在寄存器最右边8位。 sb:存储字节指令,从寄存器的最右边取1个字节并将其写入内存。 复制1个字节顺序如下…...

C#笔记(1)
解决方案: 【1】组织项目:把项目放在放在一个解决方案中,统一开发,统一编译。 【2】管理项目:开发中的任何问题,在统一编译过程中,都能随时发现。也可以添加第三方的库文件。 命名空间: 命名空…...

SSDF攻击、防御与展望
摘要: 随着无线通信业务的不断发展,频域也越来越成为了一种珍贵的稀缺资源,与此同时,相应的无线电安全问题层出不穷,为无线通信造成了十分恶劣的影响,本文从深入理解认知无线电安全开始,对一些典…...

MedMamba代码解释及用于糖尿病视网膜病变分类
MedMamba原理和用于糖尿病视网膜病变检测尝试 1.MedMamba原理 MedMamba发表于2024.9.28,是构建在Vision Mamba基础之上,融合了卷积神经网的架构,结构如下图: 原理简述就是图片输入后按通道输入后切分为两部分,一部分走…...

单点登录的要点
单点登录(SSO)是一种身份验证服务,它允许用户使用一组凭据登录一次,然后在多个应用程序中访问其他应用程序而无需重新进行身份验证。这样,用户只需一次登录即可访问整个应用生态系统,提高了用户体验并简化了…...

linux线程 | 一点通你的互斥锁 | 同步与互斥
前言:本篇文章主要讲述linux线程的互斥的知识。 讲解流程为先讲解锁的工作原理, 再自己封装一下锁并且使用一下。 做完这些就要输出一堆理论性的东西, 但博主会总结两条结论!!最后就是讲一下死锁。 那么, 废…...

全栈开发小项目
用到的技术栈: nodejswebpackknockoutmongodbPM2rabbitmq 以下是一个综合指南,展示如何将 Node.js、Webpack、Knockout.js、MongoDB、PM2 和 RabbitMQ 集成到一个项目中。 我们将在这一项目中添加 RabbitMQ,用于处理消息队列。这对于任务分…...

批处理一键创建扫描仪桌面打开快捷方式图标 简单直接有效 扫描文档图片的应急策略
办公生活中,我们在安装完多功能一体机的打印驱动之后,找不到扫描文件的地方,如果驱动程序安装正确,我们可以用系统自带的扫描仪程序调用这种打印机或复印机的扫描程序即可,它在电脑系统中的位置一般是:C:\W…...

【服务器知识】Tomcat简单入门
文章目录 概述Apache Tomcat 介绍主要特性版本历史使用场景 核心架构Valve机制详细说明请求处理过程 Tomcat安装Windows系统下Tomcat的安装与配置:步骤1:安装JDK步骤2:下载Tomcat步骤3:解压Tomcat步骤4:配置环境变量&a…...

【前端】Matter:过滤与高级碰撞检测
在物理引擎中,控制物体的碰撞行为是物理模拟的核心之一。Matter.js 提供了强大的碰撞检测机制和碰撞过滤功能,让开发者可以控制哪些物体能够相互碰撞,如何处理复杂的碰撞情况。本文将详细介绍 碰撞过滤 (Collision Filtering) 与 高级碰撞检测…...