还有六天就要考PAT了,这几天写博客回顾一下常用的算法,临时抱一下佛脚哈哈哈~
第一次写,如有错误,请多指教哈~
图篇
甲级题库中,感觉涉及到图的题大部分用Dijkstra+DFS就可以AC了,部分题涉及到了拓扑排序和BFS。因此,这里就只给出这四种简单算法。
(下面代码“/////////////////////////////////////////”以上的部分是全局变量,为了查看方便写到了函数中,有领结矩阵和领结表两种写法)
一、DFS
图的深度递归没啥好说的,注意不要走回头路和递归边界就好。
void DFS1(int index){
int G[maxn][maxn];
bool havego[maxn];
///////////////////////////////////////
for(int i=0;i<maxn;i++){
if(!havego[i]&&G[index][i]!=0){
havego[i]=true;
DFS1(i);
}
}
}
void DFS2(int index){
vector<int> G[maxn];
bool havego[maxn];
//////////////////////////////////////////////////
for(int i=0;i<G[index].size;i++){
int next=G[index][i];
if(!havego[next]){
havego[next]=true;
DFS2(next);
}
}
}
二、Dijkstra
维护一个数组d[i](起点到 i 的最短距离),每次访问经过最小距离能到达的下个结点,以该节点为中间结点更新到达它下个的结点的最短距离。如果要求输出最短路径,维护一个数组pre[i](存放第 i 个结点的前置结点)。
如果有多个最短路径,则先存放至vector<int> pre[i]中,再对其进行深度遍历,遍历过程中还可以计算其他条件(如最大点权和),具体内容参考晴神的算法笔记。这里只给出最简单的dij算法。
数据初始化:
d[s]=0;//边权
c[s]=weight[s];//点权
pre[s]=s;//前置
void dijkstra1(int s){
int G[maxn][maxn];
int d[maxn];
bool havego[maxn];
////////////////////////////////////////////////
fill(d,d+maxn,inf);
fill(havego,havego+maxn,false);
d[s]=0;
for(int i=0;i<n;i++){
int cur=-1;
int _min=inf;
for(int j=0;j<n;j++){
if(!havego[i]&&d[j]<_min){
cur=i;
_min=d[j];
}
}
if(cur==-1)return;
havego[cur]=true;
for(int j=0;j<n;j++){
if(!havego[j]&&G[cur][j]!=0&&G[cur]+G[cur][j]<d[j]){
d[j]=G[cur]+G[cur][j];
}
}
}
}
void dijkstra2(int s){
struct node{
int next;
int distance;
};
vector<node> G[maxn];
int d[maxn];
bool havego[maxn];
////////////////////////////////////////////////////
fill(d,d+maxn,inf);
fill(havego,havego+maxn,false);
d[s]=0;
for(int i=0;i<n;i++){
int cur=-1;
int _min=inf;
for(int j=0;j<n;j++){
if(!havego[i]&&d[j]<_min){
cur=i;
_min=d[j];
}
}
if(cur==-1)return;
havego[cur]=true;
for(int j=0;j<G[cur].size();j++){
int next=G[cur][j].next;
int dist=G[cur][j].distance;
if(!havego[next]){
if(d[cur]+dist<d[next]){
d[next]=d[cur]+dist;
}
}
}
}
}
三、拓扑排序
入度为零加入队列,每次将与当前结点相连的结点入度减一,如果为零则入队,最后访问的节点数等于总结点数,则拓扑成功。
bool topologicalsort(){
vector<int> G[maxn];
int ver[maxn];//入度
//////////////////////////////////////////
int ct=0;
queue<int> Q;
for(int i=0;i<n;i++){
if(ver[i]==0)
Q.push(i);
}
while(!Q.empty()){
int cur=Q.front();
Q.pop();
for(int i=0;i<G[cur].size();i++){
int next=G[cur][i];
ver[next]--;
if(ver[next]==0)
Q.push(next);
}
ct++;
}
if(ct==n)
return true;
return false;
}
四、BFS
void BFS1(int index){
int G[maxn][maxn];
bool havego[maxn];
//////////////////////////////////////////////////////
queue<int> Q;
Q.push(index);
havego[index]=true;
while(!Q.empty()){
int cur=Q.front();
Q.pop();
for(int i=0;i<maxn;i++){
if(!havego[i]&&G[index][i]!=0){
havego[i]=true;
Q.push(i);
}
}
}
}
void BFS2(int index){
vector<int> G[maxn];
bool havego[maxn];
///////////////////////////////////////////
queue<int> Q;
Q.push(index);
havego[index]=true;
while(!Q.empty()){
int cur=Q.front();
Q.pop();
for(int i=0;i<G[cur].size();i++){
int next=G[cur][i];
if(!havego[next]){
Q.push(next);
havego[next]=true;
}
}
}
}