1. 程式人生 > >外校培訓前三節課知識集合綱要(我才不會告訴你我前兩節只是單純的忘了)

外校培訓前三節課知識集合綱要(我才不會告訴你我前兩節只是單純的忘了)

day 1{

一大堆學習方法及規劃(其中告訴我可以無所忌憚的看題解哦)

1廣搜bfs {

重點:  參照---馬的遍歷bfs{

記得判重(不同於spfa)

模板:

#include <queue>
 
queue < int > q;
 
int main()

q.push( s ) , vis[s] = 1; 

while( !q.empty() )  //佇列不為空時

  {  

int now = q.front();   //取出當前元素

q.pop(); //彈出當前元素

  for( register int i = 0 ; i < linker[ now ].size() ; i++ ) //鏈式前向星寫法(可用vector) 3   :-----4-----6-----7----9

      {    

int cur = linker[ now ][i];取出某個起點後所連線(跟隨)的一系列點(fans)    

if( !vis[ cur ] )   vis[ cur ] = 1 , q.push( cur ); 若這個點未遍歷(判重)(區別於spfa) 這個點扔到佇列裡面

      } 

  }

}

//具體請見馬的遍歷

2連結串列(vector寫法)和鏈式前向星(不是特別會寫)

用vector實現鄰接表的建圖
一、vector 簡介及基本操作:

1、vector是c++中stl庫中封裝好的容器,常用定義不定長陣列來構建無向圖或有向圖

. 2、基本操作:

(1)標頭檔案#include<vector>.
 
(2)建立vector物件,vector<int> vec;
 
(3)尾部插入數字:vec.push_back(a);
 
(4)使用下標訪問元素,cout<<vec[0]<<endl;記住下標是從0開始的。
 
(5)使用迭代器訪問元素. vector<int>::iterator it; for(it=vec.begin();it!=vec.end();it++)     cout<<*it<<endl;
 
(6)插入元素:    vec.insert(vec.begin()+i,a);在第i+1個元素前面插入a;
 
(7)刪除元素:   vec.erase(vec.begin()+2);刪除第3個元素 vec.erase(vec.begin()+i,vec.end()+j)刪除區間[i,j-1];區間從0開始
 
(8)向量大小:vec.size();
 
(9)清空:vec.clear(); vector的元素不僅僅可以使int,double,string,還可以是結構體,但是要注意:結構體要定義為全域性的, 否則會出錯。
 
vector實現:vector[x].push_back(y);//把y扔到x後面去;

 

 

 

day2 {

1最短路演算法{

  一般最短路 floyd(n^3){

思想:區間dp;

模板{

for(int k=1;k<=n;k++)//遍歷中轉站

{

for(int i=1;i<=n;i++)//遍歷起點{

for(int j=1;j<=n;j++){//遍歷終點

  if(i!=j&&i!=k&&j!=k&&f[i][j]>f[i][k]+f[k][j]) //i=j值為0,i=k或j=k時中轉站是他自身無意義

f[i][j]=f[i][k]+f[k][j];

}

}

}

當然這個也可以用來做剛開始圖的個點之間是否可以走的儲存

for(int k=1;k<=n;k++)//遍歷中轉站

{

for(int i=1;i<=n;i++)//遍歷起點{

for(int j=1;j<=n;j++){//遍歷終點

  if(i!=j&&i!=k&&j!=k) //i=j值為0,i=k或j=k時中轉站是他自身無意義

f[i][j]=(f[i][k]&&f[k][j])||f[i][j];

}

}

}

Bellman-Ford演算法O(NE)

模板:

#include <bits/stdc++.h>
using namespace std;
int main(){
 // 此演算法實際上就是一點點靠近真理(最優解)的過程,n為點的個數,m為邊的個數
for(int i=1;i<=n;i++){
dis[i]=inf;  //所謂dis[i],就是起點到i之間的最短距離
} //全部設為無限大 即所有點現在還都是白點 ,都還未開通
dis[1]=0;//起點肯定是紅點 起點到起點距離肯定為0
for(int i=1;i<=n-1;i++){//最不好理解的地方 最壞就是一條直線,一次只能優化一個點到起點距離,即n-1次,不懂可以接著往下看
 for(int j=1;j<=m;j++){ //注意 在bellman-fort中 遍歷的是邊不是點
  int x=u[j],y=v[j];//x為一條邊j的初始點,y為一條邊j的終點
  if(dis[x]<inf){//一條邊的初始點必須與起點相連,這樣才能保證遍歷優化其他點到起點的距離
  //但是如果dis[x]不是最優解,那麼他所優化的其他點也都不是最優解!!!!!
   dis[y]=min(dis[y],dis[x]+w[j]);//管他的,先優化了再說(區域性優化)
  }
  //很明顯 在一次操作中,所有從起點到與紅點相鄰的邊的終點的值都被優化了一遍,但還沒有完
  //新的白點變為了紅點 所以要繼續優化;(或許可以更好哦)
  //反正遍歷的是邊,所有東西都是在一點點的區域性優化中所最終優化的 (怪不得很浪費)
  //所以說只要知道要最多進行多少次優化(n-1),優化什麼(各點到起點最短距離)
  //變數是什麼(不斷被優化的個邊之間的距離)!!
  //也許當初並不完美,也許之前得出的結論都是錯的
   //也要有追尋真理的執著
   //讓一個min來不斷優化基礎,從而改正錯誤吧
  //一個min行天下 
 }
}

return 0;
}

剩下的兩個再翻一篇吧