MyBatis 基本配置檔案
阿新 • • 發佈:2020-12-07
技術標籤:演算法neo4jdijkstrajavactwitter
/* kruskal演算法 求取MST 首先按照w權重對於所有的邊從小到大進行排序 按照最小生成樹的定義來講,就是使得所有的邊上的權重總和最小 由於是一棵樹,所以不能形成環 判斷是否為環 就是找他們的祖先,如果祖先是相同的,就證明一個是在最後,祖先是在最前, 他們在同一條鏈上,然後這邊上兩個點 相連就變成一個環了 然後的話就是N條邊只需要選取最短的M-1條邊就可以組成一顆最小生成樹 */ #include <bits/stdc++.h> #define ll long long using namespace std; const int maxn= 1e3;///1000的大小 int f[maxn];///f(i)代表節點 i 的父親 struct min_edge{ int u;///起點 int v;///終點 int w;///兩點之間的距離 }edge[maxn]; bool cmp(struct min_edge A,struct min_edge B)///按照W的大小從小到大排序 { return A.w < B.w; } int FA_find(int x)///找出他們的公共的祖先(最高層次的) { if (x!=f[x]) return FA_find(f[x]);///開始我們賦值就是他本身,如果他的父親是他本身,就說明他就是祖先 ///不是的話找他父親的父親 return x; } int main() { ///freopen("3.txt","r",stdin); ///freopen("4.txt","w",stdout); int n;///n條邊 int m;///m個節點 cin>>n>>m; for (int i=1;i<=n;++i) { cin>>edge[i].u>>edge[i].v>>edge[i].w; } sort(edge+1,edge+1+n,cmp);///按照w的大小從小到大排序 for (int i=1;i<=m;++i)f[i] = i;///首先的話節點的祖宗就是自身 int cnt = 0;///記錄當前選了多少條邊 for (int i=1;i<=n;++i)///n條邊選取m-1條 { if (cnt == m-1)break; if (FA_find(edge[i].u)!=FA_find(edge[i].v))///這條邊上的起點和終點的祖先不同就說明這兩個點之間可以連線這條邊 { f[FA_find(edge[i].v)] = FA_find(edge[i].u);///將這條邊放入我們所建的最小生成樹 此時V節點的父親要變成U的祖先 ///因為他們現在在一條鏈上了 printf("%d %d\n",edge[i].u,edge[i].v); ++cnt; } } return 0; }
prim此處用鄰接矩陣存圖,沒有判斷重邊 有需要可以自判 或者改用vector或者鏈式前向星
/* prim演算法 加點操作 首先確定一個節點,然後找到離他最近的節點B 普里姆演算法 接下來找到離節點B最近的節點 如此迴圈回溯 但是走過的節點需要標記一下 */ #include <bits/stdc++.h> #define ll long long using namespace std; const int maxn= 1e3; const int INF=0x3f3f3f3f;/// 一個極大值 int disc[maxn];///儲存最短距離 disc[i] 第i個節點最短距離 初始值就是節點1到各個點之間的距離W ,不存在就是INF(無窮大) int close[maxn];///儲存最短的連線點 close[i]代表離節點i最近的那個節點 int G[maxn][maxn];///鄰接矩陣 G[i][j]起點i 終點j上存在一條重w的邊 bool vis[maxn];///標記陣列,如果當前的節點被找過就為1 int main() { /// freopen("1.txt","r",stdin); ///freopen("2.txt","w",stdout); ///ios::sync_with_stdio(false); ///cin.tie(0); ///cout.tie(0); memset(vis,false,sizeof(vis));///相當於for(int i-0;i<=n;++i) vis[i]=false; memset(G,INF,sizeof(G));///同理 因為你要找最短的距離,所以不存在的邊就是距離無窮大 int n;///n條邊 int m;///m個節點 cin>>n>>m; for (int i=0;i<n;++i) { int u,v,w; cin>>u>>v>>w;///起始點 終點 權重 G[u][v] = w;///存邊 G[v][u] = w;///存邊 無向圖兩條邊 } for (int i=1;i<=n;++i) { disc[i] = G[1][i];///首先都儲存起點為1終點為i的邊 //cout<<disc[i]<<endl; close[i] = 1;///離i最近的此時的邊就是1 } int idx=1;///距離最短的節點下標 for (int i=1;i<m;++i) { int mine=INF;///由於要找到最小值 所以要賦值一個最大的數值 vis[idx] = true;///當前這個最小的節點用過 所以標記為1 for (int j=1;j<=m;++j) { if (!vis[j]&&mine>disc[j])///從沒有選過的最短路徑中找到離 當前節點最近的那個節點的下標idx { idx = j; mine = disc[j]; } } if (mine == INF){puts("No construct");return 0;}/// 原圖不聯通 無法找出最小生成樹 cout<<idx<<"->"<<' '<<close[idx]<<endl; // cout<<disc[idx]<<endl; for (int k=1;k<=m;++k)///找到離當前節點最近的下標idx { if (G[idx][k]<disc[k]&&!vis[k])///更新disc 從idx出發 如果這條邊到k的距離小於剛剛那個節點的就可以直接更新 { disc[k] = G[idx][k]; close[k] = idx;///此時離他最近的就是idx節點 } } } cout<<endl; return 0; }
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn= 1e6; const int INF=INT_MAX;/// 一個極大值 int disc[maxn];///儲存最短距離 disc[i] 第i個節點最短距離 初始值就是節點1到各個點之間的距離W ,不存在就是INF(無窮大) int close[maxn];///儲存最短的連線點 close[i]代表離節點i最近的那個節點 struct Node { int v; int w; Node(int vv=INF,int ww=INF):v(vv),w(ww){} }; vector<Node>G[maxn];/// vector建圖 bool vis[maxn];///標記陣列,如果當前的節點被找過就為1 int all = 0; signed main() { ///freopen("1.txt","r",stdin); ///freopen("2.txt","w",stdout); ///ios::sync_with_stdio(false); ///cin.tie(0); ///cout.tie(0); memset(vis,false,sizeof(vis));///相當於for(int i-0;i<=n;++i) vis[i]=false; memset(disc,0x7f,sizeof(disc)); int n;///n條邊 int m;///m個節點 cin>>m>>n; for(int i=1; i<=m; i++) { G[i].clear(); } for (int i=0;i<n;++i) { int u,v,w; cin>>u>>v>>w;///起始點 終點 權重 G[u].push_back(Node(v,w)); G[v].push_back(Node(u,w)); } ///for (int i=1;i<=m;++i)disc[i] = INF; for (int i=0;i<G[1].size();++i) { disc[G[1][i].v] = min(G[1][i].w,disc[G[1][i].v]);///首先都儲存起點為1終點為i的邊 記得判斷重邊 ///cout<<disc[i]<<endl; //cout<<disc[i]<<endl; close[G[1][i].v] = 1;///離i最近的此時的邊就是1 } vis[1] = true; for (int i=1;i<m;++i) { int mine=INF;///由於要找到最小值 所以要賦值一個最大的數值 int idx = -1; for (int j=1;j<=m;++j) { if (!vis[j]&&mine>disc[j])///從沒有選過的最短路徑中找到離 當前節點最近的那個節點的下標idx { idx = j; mine = disc[j]; } } if (mine == INF){puts("orz");return 0;}/// 原圖不聯通 無法找出最小生成樹 all += mine; vis[idx] = true; ///cout<<idx<<"->"<<' '<<close[idx]<<endl; ///cout<<disc[idx]<<endl; for (int k=0;k<G[idx].size();++k) { if (!vis[G[idx][k].v]&&G[idx][k].w<disc[G[idx][k].v])///更新disc 從idx出發 如果這條邊到k的距離小於剛剛那個節點的就可以直接更新 { disc[G[idx][k].v] = G[idx][k].w; close[G[idx][k].v] = idx;///此時離他最近的就是idx節點 } } } cout<<all<<endl; return 0; }