<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      搜索(八皇后) 洛谷P1219

      //搜索的實(shí)現(xiàn)。 
      //優(yōu)化dfs1。 
      //八皇后。 
      //n個(gè)皇后在不在同一條直線或同一條斜線,一共多少方案。
      #include<iostream>
      #include<cstdio>
      using namespace std; 
      int n,ans=0;  
      int pos[maxn];//pos[i]代表第i行的皇后放在了第pos[i]列。 
      void dfs(int now){//現(xiàn)在要去嘗試放第now行的皇后。 
          if(now>n){
              ans++;
              return;
          } 
          for(int j=1;j<=n;j++){//第now行的皇后放在第j列。 
              bool able=true;
              for(int i=1;i<now;i++){//枚舉第i行的皇后。 
                  if(pos[i]=j||abs(now-i)==abs(j-pos[i])){
                      able=false;
                      break;
                  }
              }
              if(able){
                  pos[now]=j;
                  dfs(now+1);
              }
          }
      } 
      int main(){
          n=13;//3.68s。 
          dfs(1);
          cout<<ans<<endl;
          return 0; 
      } 

       

       

      優(yōu)化dfs2。

      判斷第i行、第i條斜線上有沒有皇后。

      斜線=i+j-1>。

      #include<iostream>
      #include<cstdio>
      using namespace std; 
      int n,ans=0; 
      int pos[20];//pos[i]代表第i行的皇后放在了第pos[i]列。 
      bool col[20];//col[i] 代表第i條的直線有沒有皇后。 
      bool xie1[50];//xie[1] 代表第i條從左上到右下的斜線有沒有皇后。
      bool xie2[50];//xie[2] 代表第i條從右上到左下的斜線有沒有皇后。 
      void dfs(int now){//現(xiàn)在要去嘗試放第now行的皇后。 
          if(now>n){
              ans++;
              return;
          } 
          for(int j=1;j<=n;j++){//第now行的皇后放在第j列。
              int ibx1=j-now+n;//從左上到右下的斜線編號(hào)。 
              int ibx2=now+j-1;//從右上到左下的斜線編號(hào)。 
              if(!col[j]&&!xie1[idx1]&&!xie2[idx2]){
                  pos[now]=j;
                  col[j]=xie1[idx1]=xie2[idx2]=true; 
                  dfs(now+1);
                  col[j]=xie1[idx1]=xie2[idx2]=false;
              }
          }
      } 
      int main(){
          n=13;//0.6141s。 
          n=14;//3.494s。
          dfs(1);
          cout<<ans<<endl;
          return 0; 
      }

       

       

      圖論:
      圖的概念 由點(diǎn)和邊構(gòu)成的元素
      邊:如果邊都有方向 我們叫它有向圖 沒方向叫無向圖
      一、圖的一些基本概念:

      1.度:一個(gè)頂點(diǎn)連了幾條邊 就是它多少度
      2.有向圖里的入度和出度:連向自己的度就是入度 往外連得就是出度
      3.有向圖里的自環(huán):既是入度又是出度
      4.路徑:只要沿著邊走叫做路徑 如:1 -> 2 -> 3 -> 2 -> 1
      5.簡(jiǎn)單路徑:不能走重復(fù)點(diǎn)和邊的路徑 如:1 -> 2 -> 3u
      6.環(huán):起點(diǎn)等于終點(diǎn)的路徑(繞起來)  如:1 -> 2 -> 1
      7.簡(jiǎn)單環(huán):起點(diǎn)等于終點(diǎn)且保證除起點(diǎn)和終點(diǎn)外不經(jīng)過重復(fù)的點(diǎn)和邊

      圖的分類方式:1.樹:無向、無環(huán)、連通(任意兩個(gè)點(diǎn)之間都可以互相走到)

      如果有一個(gè)n個(gè)點(diǎn)的樹,它一定會(huì)有n - 1條邊

      2. 森林:無向、無環(huán)(很多棵樹)形象!

      3.有向樹:無環(huán)、連通

      外向樹:如果所有邊都指向外邊

      內(nèi)向樹:如果所有邊都指向一點(diǎn)

      注意:有可能一棵樹既是外向樹又是內(nèi)向樹!

      4.章魚圖:無向、連通、有環(huán)且只有一環(huán)

      章魚圖的每一個(gè)點(diǎn)向往外延伸 一定是一棵樹。如果一個(gè)章魚圖有n個(gè)點(diǎn),它就一定有n條邊

      章魚圖想要變成樹,只需要去掉環(huán)上的一條邊

      一棵樹想要變成章魚圖,只需加一條邊

      5.DAG  ——>   有向無環(huán)圖

      6.二分圖(無向圖)  --> 能夠把所有的邊分為兩部分不要求聯(lián)通

      見圖:

      樹和森林一定是二分圖

      判斷:沒有奇環(huán)(即奇數(shù)個(gè)頂點(diǎn)組成的環(huán)) 就是二分圖

       

      二、代碼實(shí)現(xiàn)存

      1.鄰接矩陣存圖

       

      int z[101][101];
      //z[i][j] 代表i到j(luò)那條邊的長(zhǎng)度 
      int main(){
          cin >> n >> m;
          for(int i = 1; i <= n; i++){
              int s,e,d;
              cin >> s >> e >> d;//起點(diǎn)為s,終點(diǎn)為e,長(zhǎng)度為d
              z[s][e] = d;//有向圖 
              //z[e][s] = d; 無向圖 
          } 
      }

       

      壞處:內(nèi)存消耗比較大

      好處:簡(jiǎn)潔、快(因?yàn)橹灰纈到j(luò)的那條邊的信息 O(1))

       

      2.邊表存圖

      vector< pair<int,int> > z[maxn];
      //z[i]:代表 所有以i為起點(diǎn)的所有邊
      //z[i][j] :代表所有以i為起點(diǎn)的第j條邊
      //z[i][j].forst:代表i為起點(diǎn)的第j條邊的終點(diǎn)
      //z[i][j].second: 代表i為起點(diǎn)的第j條邊的起點(diǎn) 
      void add_edge(int s, int e, int d){
          z[s].push_back(make_pair(e,d));
          //push_back:向vector的末尾添加一個(gè)元素 
      }
      int main(){
          cin >> n >> n;
          for(int i = 1; i <= n; i++){//添加一條從s出發(fā),到e 長(zhǎng)度為d的邊 
              int s,e,d;
              cin >> s >> e >> d;
              add_edge(s,e,d);//添加一條邊 STL函數(shù) 
              add_edge(e,s,d);//無向圖 
          }
          for(int i = 1; i <= n; i++)
              for(int j = 0; j < z[i].size();j++){
                  int e = z[i][j].first;
                  int d = z[i][j].second;
                  //代表當(dāng)前的邊 是從i開始的第j條邊 終點(diǎn)為e 長(zhǎng)度為d 
              }
      }

      優(yōu)點(diǎn):改善了上一種方法的內(nèi)存

      缺點(diǎn):慢

       

      三、解決一些問題

      1.一張圖 有n個(gè)點(diǎn) me 條邊 并且是一張無向圖 請(qǐng)判斷是否是二分圖(二分圖染色)

      思路:染色法從一號(hào)點(diǎn)開始 將其染色為1 與它相鄰的點(diǎn)應(yīng)當(dāng)是第二部分 ;與第二部分相鄰的點(diǎn)就是第一部分。如果能夠成功將所有的點(diǎn)都染色 就是二分圖 如果一個(gè)點(diǎn)的兩邊的點(diǎn)顏色相同就不是二分圖

      注意:這里其實(shí)有一個(gè)坑,我們從一號(hào)點(diǎn)開始 如果我們的圖不連通就無法找到所有點(diǎn),所以需要枚舉

       

      vector<int > z[maxn];
      //z[i]:代表 所有以i為起點(diǎn)的所有邊
      //z[i][j] :代表所有以i為起點(diǎn)的第j條邊
      //z[i][j].forst:代表i為起點(diǎn)的第j條邊的終點(diǎn)
      //z[i][j].second: 代表i為起點(diǎn)的第j條邊的起點(diǎn) 
      void add_edge(int s, int e){
          z[s].push_back(e);
          //push_back:向vector的末尾添加一個(gè)元素 
      }
      int col[maxn];
      //col[i] == 0 代表還沒有染色
      //否則代表第i個(gè)點(diǎn)的顏色
       
      int main(){
          cin >> n >> n;
          for(int i = 1; i <= n; i++){//添加一條從s出發(fā),到e 長(zhǎng)度為d的邊 
              int s,e;
              cin >> s >> e;
              add_edge(s,e);//添加一條邊 STL函數(shù) 
              add_edge(e,s);//無向圖 
          }
          for(int i = 1; i <= n; i++){
              if(col[i] != 0) continue;
              col[1] = 1;
              queue<int> q;//可以改變周圍點(diǎn)顏色的點(diǎn)
              q.push(1);
              while(q.size()){
                  int i = q.front();
                  q.pop();
                  for(int j = 0; j < z[i].size(); j++){
                      int k = z[i][j];
                      //i -> k 的一條邊 
                      if(!col[k]){
                          col[k] = 3 - col[i];
                          q.push(k);
                      }
                      else{
                          if(col[k] !== col[i]){
                              cout << "不是二分圖!" << endl;
                              exit(0);
                          }
                      }
                  }
              } 
          }
          cout << "是二分圖 !"<< endl;//順利完成整個(gè)程序 
          return 0; 
      }

       

       

      2.拓?fù)渑判颍ㄡ槍?duì)DAG

      保證排完序之后原圖當(dāng)中存在的邊都是從左向右指的,叫做拓?fù)渑判颉?/strong>

      如果一個(gè)點(diǎn)的入度為零 應(yīng)把它放在最前面 把每次入讀為0的點(diǎn)更新實(shí)現(xiàn):

      vector<int > z[maxn];
      //z[i]:代表 所有以i為起點(diǎn)的所有邊
      //z[i][j] :代表所有以i為起點(diǎn)的第j條邊
      //z[i][j].forst:代表i為起點(diǎn)的第j條邊的終點(diǎn)
      //z[i][j].second: 代表i為起點(diǎn)的第j條邊的起點(diǎn) 
      void add_edge(int s, int e){
          z[s].push_back(e);
          //push_back:向vector的末尾添加一個(gè)元素 
      }
      int col[maxn];
      //col[i] == 0 代表還沒有染色
      //否則代表第i個(gè)點(diǎn)的顏色
      int in[maxn];//代表i點(diǎn)的入度 是多少 
      int main(){
          cin >> n >> n;
          for(int i = 1; i <= n; i++){//添加一條從s出發(fā),到e 長(zhǎng)度為d的邊 
              int s,e;
              cin >> s >> e;
              add_edge(s,e);//添加一條邊 STL函數(shù) 
              in[e] ++;
          }
          int cnt = 0;
          for(int i = 1; i <= n; i++)
              if(in[i] == 0) resault[++cnt] = i; 
          for(int i = 1; i <= n; i++){//當(dāng)前要取出的拓?fù)渑判虻慕Y(jié)果中的第i個(gè)點(diǎn) 
              int p = result[i];
              for(int j = 0; j < z[p].size(); j++){
                  int q = z[p][j];//p -> q的邊 
                  in[q] --;
                  if(in[q] == 0) result[++cnt] = q;
              }
          }    
          return 0; 
      }

       插播一點(diǎn)小概念:每個(gè)節(jié)點(diǎn)在第幾層叫做這個(gè)節(jié)點(diǎn)的深度

      祖先:在i上面的節(jié)點(diǎn)

      lca(i,j) = i 和j的最近公共祖先

      Q;給出樹 求出lca(i,j)

      vector<int > z[maxn];
      //z[i]:代表 所有以i為起點(diǎn)的所有邊
      //z[i][j] :代表所有以i為起點(diǎn)的第j條邊
      //z[i][j].forst:代表i為起點(diǎn)的第j條邊的終點(diǎn)
      //z[i][j].second: 代表i為起點(diǎn)的第j條邊的起點(diǎn)
      void add_edge(int s, int e){
          z[s].push_back(e);
          //push_back:向vector的末尾添加一個(gè)元素
      }
      void dfs(int i, int j){//i 的父節(jié)點(diǎn)是j
          f[i] = j;
          depth[i] = depth[j] + 1;
          for(int k = 0; k < z[i].size();k++){
              int l = z[i][k];//這條邊是從 i -> l的邊
              if(l != j) dfs(l,i);
          }
      }
      void get_lca(int p1, int p2){
          while(p1 != p2){
              if(depth[p1] < depth[p2]) swap(p1,p2);
              p1 = f[p1];
          }
          return p1;
      }

      int depth[maxn], f[maxn];//深度 父節(jié)點(diǎn)
      int main(){
          cin >> n >> n;
          for(int i = 1; i <= n; i++){//添加一條從s出發(fā),到e 長(zhǎng)度為d的邊
              int s,e;
              cin >> s >> e;
              add_edge(s,e);//添加一條邊 STL函數(shù)
              add_edge(e,s);
          }
          dfs(1,0);
          return 0;
      }

      優(yōu)化:倍增求lca

      int depth[maxn], f[maxn][20];//深度  從i 
      vector<int > z[maxn];
      //z[i]:代表 所有以i為起點(diǎn)的所有邊
      //z[i][j] :代表所有以i為起點(diǎn)的第j條邊
      //z[i][j].forst:代表i為起點(diǎn)的第j條邊的終點(diǎn)
      //z[i][j].second: 代表i為起點(diǎn)的第j條邊的起點(diǎn) 
      void add_edge(int s, int e){
          z[s].push_back(e);
          //push_back:向vector的末尾添加一個(gè)元素 
      }
      void dfs(int i, int j){//i 的父節(jié)點(diǎn)是j 
          f[i][0] = j;
          for(int k = 1; k < 20; k++){
              f[i][k] = f[f[i][k - 1] ][k - 1];
          }
          
          depth[i] = depth[j] + 1;
          for(int k = 0; k < z[i].size();k++){
              int l = z[i][k];//這條邊是從 i -> l的邊
              if(l != j) dfs(l,i); 
          }
      }
      void get_lca(int p1, int p2){
          //把p1 p2深度調(diào)整成一樣的
          else if(depth[p1] < depth[p2]) swap(p1, p2);
          for(int i = 19; i >= 0; i--)
              if(depth[f[p1][i]] >= depth[p2]) p1 = f[p1][i];
          if(p1 == p2) return p1;
          for(int i = 19; i >= 0; i--)
              if(f[p1][i] != f[p2][i]) p1 = f[p1][i], p2 = f[p2][i];
          return f[p1][0];
      }
      
      int main(){
          cin >> n >> n;
          for(int i = 1; i <= n; i++){//添加一條從s出發(fā),到e 長(zhǎng)度為d的邊 
              int s,e;
              cin >> s >> e;
              add_edge(s,e);//添加一條邊 STL函數(shù) 
              add_edge(e,s);
          }
          dfs(1,0);
          return 0; 
      }

       

      posted on 2023-07-11 14:46  Slz_konnyaku  閱讀(24)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 少妇爽到呻吟的视频| 中文字幕有码无码AV| 色综合久久精品中文字幕| 午夜免费无码福利视频麻豆| 精品国产中文字幕在线| 国产三级精品片| 无码人妻一区二区三区在线视频 | 国产喷水1区2区3区咪咪爱AV| 精品久久人人妻人人做精品| 久久99精品久久久大学生| 日韩有码国产精品一区| 山西省| 性色欲情网站iwww九文堂| 亚洲少妇一区二区三区老| 国产精品内射在线免费看| 野花社区www视频日本| 狠狠五月深爱婷婷网| 欧美www在线观看| 日韩国产成人精品视频| 视频二区中文字幕在线| 亚洲av永久无码精品网站| аⅴ天堂中文在线网| 久久影院九九被窝爽爽| 化德县| 国产偷国产偷亚洲综合av| 国产精品一线天粉嫩av| 久久99国产精品尤物| 综合亚洲网| 无码国内精品久久人妻蜜桃| 一亚洲一区二区中文字幕| 色悠悠国产精品免费在线| 又污又黄又无遮挡的网站| 国产午精品午夜福利757视频播放| 精品少妇人妻av无码久久| 亚洲性日韩精品一区二区| 欧美国产日韩在线三区| 韩国免费a级毛片久久| 女人腿张开让男人桶爽| 国产午精品午夜福利757视频播放 国产午夜亚洲精品国产成人 | 国产亚洲精品AA片在线播放天| 国产女同疯狂作爱系列|