還有六天就要考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;
}
}
}
}