SH演算法
㈠ 數字證書的簽名哈希演算法跟指紋演算法都是指對摘要(指紋的)的編碼嗎
證書簽名使用的演算法是發布者自己規定的 使用自己的私鑰對證書編碼的哈希值進行加密 一般演算法為md5withrsa或者sha256withrsa。哈希演算法是唯一的 就是把證書編碼轉換為固定長度的2進制 這個過程不可逆 就是說無法通過哈希值還原證書編碼。指紋演算法就是哈希演算法 一般都是sh1。證書認證的流程是證書所有者把證書和指紋(證書的哈希值並用私鑰加密)發給用戶 用戶根據證書計算出一個哈希值 用公鑰解密指紋得到一個哈希值 看一下兩者是否相同 相同及證明證書未被篡改。演算法是由所有者的私鑰加密的。ca的作用是ca是可以認證一個證書鏈,源頭就是ca 一旦你信任了這個ca 就是信任了ca發布的證書,這樣你與ca發布的證書的所有者通信時可以根據證書鏈找到ca ca可信任了則這個發布者就是可信任的
㈡ 體積計算公式
體積計算公式是用於計算體積的公式。即計算各種幾何體體積的數學算式。
柱體:
常規公式:V=Sh(S是底面積,h是高)
圓柱:V=πr²h(r代表底圓半徑,h代表圓柱體的高)
稜柱:(V=Sh底面積×高)
長方體:V=abc(a、b、c分別表示長方體的長、寬、高)
正方體:V=a³(a表示正方體的棱長)
沃思是一個具有熱切愛國情懷的人,成名後的他婉拒了斯坦福大學的挽留,於1967年回到祖國,先在蘇黎世大學教書,但第二年就回到他的母校蘇黎世工學院。在這里,他先是設計與實現了 PASCAL語言,這是在 CDC 6600上開發成功的。 PASCAL在數據結構和過程式控制制結構方面都有很多創造。對於前者,除一般的整型、實型、布爾型數據外,PASCAL還增加了字元型、子域類型、記錄結構類型、文件類型、集合類型和指針類型;對於過控制結構方面,除了保留了無條件轉移的GOTO語句外,又增加了if-then-else、case、while、repeat和for等多種控制結構,還允許復合語句和處理記錄變數的分量使用with語句這種編寫形式。可以說,現代程序設計語言中常用的數據結構和控制結構絕大多數都是由PASCAL語言奠定基礎的,因此它在程序設計語言的發展史上具有承上啟下的重要里程碑意義。
㈢ sh實現最小生成樹和最短路徑的演算法
圖的最小生成樹與最短路徑的演算法
一、圖的生成樹與最小生成樹
在一個連通圖G中,如果取它的全部頂點和一部分邊構成一個子圖G』,即:
若邊集E(G』)中的邊既將圖中的所有頂點連通又不形成迴路,則稱子圖G』是原圖G的一棵生成樹。
最小生成樹:給圖中每個邊賦一權值,所有生成樹中所選擇邊的權值之和最小的生成樹,稱之為最小代價生成樹,即是最小生成樹。
1、普里姆演算法
1.1演算法描述
假設G=(V, E)是一個具有n個頂點的連通網,T=(U, TE)是G的最小生成樹,其中U是T的頂點集,TE是T的邊集,U和TE的初值均為空集。演算法開始時,首先從V中任取一個頂點(假定取v1),將它並入U中,此時U={v1},然後只要U是V的真子集(即),就從那些其一個端點已在T中,另一個端點仍在T外的所有邊中,找一條最短(即權值最小)邊,假定為(vi, vj),其中,並把該邊(vi, vj)和頂點vj分別並入T的邊集TE和頂點集U,如此進行下去,每次往生成樹里並入一個頂點和一條邊,直到(n-1)次後就把所有n個頂點都並入到生成樹T的頂點集中,此時U=V,TE中含有(n-1)條邊,T就是最後得到的最小生成樹。 1.2關鍵問題
普里姆演算法的關鍵之處是:每次如何從生成樹T中到T外的所有邊中,找出一條最短邊。例如,在第k次前,生成樹T中已有k個頂點和(k-1)條邊,此時T中到T外的所有邊數為k(n-k),當然它包括兩頂點間沒有直接邊相連,其權值被看作為「無窮大」的邊在內,從如此多的邊中查找最短邊,其時間復雜性為O(k(n-k)),顯然是很費時的。是否有一種好的方法能夠降低查找最短邊的時間復雜性呢? 1.3 解決方法
方法是:假定在進行第k次前已經保留著從T中到T外每一頂點(共(n-k)個頂點)的各一條最短邊,進行第k次時,首先從這(n-k)條最短邊中,找出一條最最短的邊(它就是從T中到T外的所有邊中的最短邊),假設為(vi, vj),此步需進行(n-k)次比較;然後把邊(vi, vj)和頂點vj分別並入T中的邊集TE和頂點集U中,此時T外只有n-(k+1)個頂點,對於其中的每個頂點vt,若(vj, vt)邊上的權值小於已保留的從原T中到vt的最短邊的權值,則用(v, vt)修改之,使從T中到T外頂點vt的最短邊為(vj, vt),否則原有最短邊保持不變,這樣,就把第k次後從T中到T外每一頂點vt的各一條最短邊都保留下來了。為進行第(k+1)次運算做好了准備,此步需進行(n-k-1)次比較。所以,利用此方法求第k次的最短邊共需比較2(n-k)-1次,即時間復雜性為O(n-k)。
1.4 prim演算法:
設一個輔助數組closedge,以記錄從U到V—U具有最小代價的邊。數組中的每個元素closedge[v]是記錄類型,包含兩個域: closedge[v].lowcast=Min{cost(u,v)|u∈U}; closedge[v].vex存儲該邊依附的在U中的頂點。
proc mintree_prim(gn:adjmatrix;u0:integer);
begin
for v:=1 to n do
if v<>u0 then
with closedage[v] do [vex:=u0; lowcast:=gn[u0,v];]
closedge[u0].lowcast:=0;{並入U集合}
for i:=1 to n-1 do
begin
v:=min(closedge);{尋找代價最小的邊}
write(closedge[v].vex,v); closedge[v].lowcast:=0;{並入U集合}
for k:=1 to n do
if gn[v,k]<closedge[k].lowcast then
begin closedge[k].lowcast:=gn[v,k]; closedge[k].vex:=v; end;
end;
end; 練習1:prim演算法實現
【問題描述】從文件中讀入連通帶權圖的信息,按prim演算法求出該圖的最小生成樹,以V1作為初始結點。
【輸入文件】第一行兩個整數m和n,分別表示圖的結點數和圖中的邊數。以下n行表示n條邊:每一行三個數x、y和k,k表示x與y之間邊的權值。
【輸出文件】共m行,第一行:最小生成樹的權;以下m-1行表示選取的邊,邊的第1個結點小於第2個結點,並按結點由小到大輸出。
【示例】輸入:5 7 輸出:45
1 2 17 1 4
2 3 30 1 5
1 4 5 2 4
2 4 10 3 5
3 4 24
3 5 7
1 5 23
練習2: Eddy painting
Eddy begins to like painting pictures recently ,he is sure of himself to become a painter.Every day Eddy draws pictures in his small room, and he usually puts out his newest pictures to let his friends appreciate. but the result it can be imagined, the friends are not interested in his picture.Eddy feels very puzze,in order to change all friends 's view to his technical of painting pictures ,so Eddy creates a problem for the his friends of you.
Problem descriptions as follows: Given you some coordinates pionts on a drawing paper, every point links with the ink with the straight line, causes all points finally to link in the same place. How many distants does your ty discover the shortest length which the ink draws?
Input:
The first line contains 0 < n <= 100, the number of point. For each point, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the point.
Input contains multiple test cases. Process to the end of file.
Output:
Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the points.
Sample Input:
3
1.0 1.0
2.0 2.0
2.0 4.0
Sample Output:
3.41
2、克魯斯卡爾演算法
2.1 演算法描述
假設G=(V,E)是一個具有n個頂點的連通網,T=(U,TE)是G的最小生成樹,U的初值等於V,即包含有G中的全部頂點,TE的初值為空。此演算法的基本思想是,將圖G中的邊按權值從小到大的順序依次選取,若選取的邊使生成樹T不形成迴路,則把它並入TE中,保留作為T的一條邊,若選取的邊使生成樹T形成迴路,則將其舍棄,如此進行下去,直到TE中包含有n-1條邊為止。此時的T即為最小生成樹。
2.2 關鍵問題
克魯斯卡爾演算法的關鍵之處是:如何判斷欲加入的一條邊是否與生成樹中已選取的邊形成迴路。這可將各頂點劃分為所屬集合的方法來解決,每個集合中的頂點表示一個無迴路的連通分量。演算法開始時,由於生成樹的頂點集等於圖G的頂點集,邊集為空,所以n個頂點分屬於n個集合。每個集合中只有一個頂點,表明頂點之問互不連通。
2.3 Kruskal演算法:
proc mintree_krusk(gn:adjmatrix);
begin
for i:=1 to n do
un[i]:=i;
for i:=1 to n-1 do
begin
minedge(a,b);
write(a,b,gn[a,b]);
k:=un[b];
for i:=1 to n do {兩個連通分量合並}
if un[i]=k then un[i]:=un[a];
end;
end;
2.4 注意:
proc minedge(var a:integer;var b:integer);用於在剩下的邊中選取不再同一連通分量上的最小代價的邊,邊的結點分別為a和b。
為了實現該過程,可以將圖中的邊生成一邊結點(包含兩個頂點和代價)數組,由小到大排序,然後通過排序後的數組進行處理;
un數組:用來記載隨著邊的加入,各頂點屬於哪個連通分量。
練習3:Kruskal演算法實現
【問題描述】從文件中讀入連通帶權圖的信息,按Kruskal演算法求出該圖的最小生成樹,以V1作為初始結點。
【輸入文件】第一行兩個整數m和n,分別表示圖的結點數和圖中的邊數。以下n行表示n條邊:每一行三個數x、y和k,k表示x與y之間邊的權值。
【輸出文件】共m行,第一行:最小生成樹的權;以下m-1行表示選取的邊,按選取邊的權值由小到大輸出。
【示例】輸入:5 7 輸出:45
1 2 17 1 4
2 3 30 3 5
1 4 5 2 4
2 4 10 1 5
3 4 24
3 5 7
1 5 23
練習4:判斷最小生成樹是否唯一
Given a connected undirected graph, tell if its minimum spanning tree is unique.
Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.
Input
The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.
Output
For each input, if the MST is unique, print the total cost of it, or otherwise print the string 'Not Unique!'.
Sample Input
2
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2
Sample Output
3
Not Unique!
二、最短路徑
【問題描述】由於從一頂點到另一頂點可能存在著多條路徑。每條路徑上所經過的邊數可能不同,即路徑長度不同,我們把路徑長度最短(即經過的邊數最少)的那條路徑叫做最短路徑,其路徑長度叫做最短路徑長度或最短距離。求圖中一頂點vi到其餘各頂點的最短路徑和最短距離比較容易,只要從該頂點vi,出發對圖進行一次廣度優先搜索遍歷,在遍歷時記下每個結點的層次即可。
若圖是帶權圖(假定權值非負)從源點vi到終點vj的每條路徑上的權(它等於該路徑上所經邊上的權值之和,稱為該路徑的帶權路徑長度)可能不同,我們把權值最小的那條路徑也稱做最短路徑,其權值也稱作最短路徑長度或最短距離。
實際上,這兩類最短路徑問題可合並為一類,這只要把第一類的每條邊的權都設為1就歸屬於第二類了,所以在以後的討論中,若不特別指明,均是指第二類的最短路徑問題。
求圖的最短路徑問題包括兩個子問題:一是求圖中一頂點到其餘各頂點的最短路徑,二是求圖中每對頂點之間的最短路徑。下面分別進行討論。
始點 終點 最短路徑 路徑長度
v0 v1 No path
v2 (v0,v2) 10
v3 (v0,v4,v3) 50
v4 (v0,v4) 30
v5 (v0,v4,v3,v5) 60
始點 終點 最短路徑 路徑長度
v1 V2 (v1,v2) 10
V3 (v1,v2,v3) 27
V4 (v1,v5,v4) 20
v5 (v1,v5) 7
1、從一頂點到其餘各頂點的最短路徑
1.1 描述
迪傑斯特拉(Dijkstra)於1959年提出了解決此問題的一般演算法,具體做法是按照從源點到其餘每一頂點的最短路徑長度的升序依次求出從源點到各頂點的最短路徑及長度,每次求出從源點vi到一個終點vj的最短路徑及長度後,都要以vj作為新考慮的中間點,用vi到vj的最短路徑和最短路徑長度對vi到其它尚未求出最短路徑的那些終點的當前路徑及長度作必要的修改,使之成為當前新的最短路徑和最短路徑長度,當進行n-2次後演算法結束。
1.2 Dijkstra演算法:
首先,引進一個輔助向量dist,dist[i]表示當前所找到的從始點V到每個終點Vi的最短路徑長度。其初態為:若<v,vi>存在,則dist[i]為其上的權值,否則為最大值(計算機能表示)。
演算法:(1)用鄰接矩陣cost表示帶權有向圖。S表示已找到的從v出發的最短路徑的終點的集合,初態為空。dist向量的初值為:dist[v,i]=cost[v,i];
(2)選擇vj,使得:dist[j]=Min{dist[i]|vi∈V-S};vj就是當前求得從v出發的最短路徑的終點。
S=S+{j};
(3)修改從v出發到集合V-S上任意頂點vk可達的最短路徑長度。
if dist[j]+cost[j,k]<dist[k] then dist[k]:=dist[j]+cost[j,k];
(4)重復(2)(3)共n-1次。
代碼:proc short_dij;
begin
for i:=1 to n do
begin
dist[i]:=cost[v0,i];
if dist[i]<max then path[i]:=v0 else path[i]:=-1; end;
flag[I]:=true;
for k:=1 to n-1 do
begin
wm:=max; j:=v0;
for i:=1 to n do
if not(flag[i]) and (dist[i]<wm) then begin j:=i; m:=dist[i]; end;
flag[j]:=true; for i:=1 to n do if not(flag[i]) and (dist[j]+cost[j,i]<dist[i]) then
begin dist[i]:=dist[j]+cost[j,i]; path[i]:=j; end;
end;
end; 其中:cost:鄰接矩陣;
path[i]:存儲從v0到頂點i的最短路徑;是以集合作為數組元素;
dist[i]:存儲相應路徑長度;
flag[i]:表示已處理的頂點。
練習5:Dijkstra演算法練習
【問題描述】從文件中讀入帶權圖的信息,按Dijkstra演算法根據給定源點求出從源點法到該圖中其餘頂點的最短路徑。
【輸入文件】第一行:一個整數L:L=0表示無向圖,L=1表示有向圖;第二行三個整數m、n和k,分別表示圖的結點數、圖中的邊數以及源點。以下n行表示n條邊:每一行三個數x、y和z,z表示x與y之間邊的權值。
【輸出文件】共m-1行,每一行的數據包括:頂點: 最短路徑:路徑,如果不存在路徑,數據為:頂點:No path。
【示例】輸入:1 輸出:2:No path
6 8 1 3:10:1 3
1 3 10 4:50:1 5 4
1 5 30 5:30:1 5
1 6 100 6:60:1 5 4 6
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60
練習6:路由選擇問題
【問題描述】
X城有一個含有N個節點的通信網路,在通信中,我們往往關心信息從一個節點I傳輸到節點J的最短路徑。遺憾的是,由於種種原因,線路中總有一些節點會出故障,因此在傳輸中要避開故障節點。
任務一:在己知故障節點的情況下,求避開這些故障節點,從節點I到節點J的最短路徑S0。
任務二:在不考慮故障節點的情況下,求從節點I到節點J的最短路徑S1、第二最短路徑S2。
【輸入文件】
第1行: N I J (節點個數 起始節點 目標節點)
第2—N+1行: Sk1 Sk2…SkN (節點K到節點J的距離為SkJ K=1,2,……,N)
最後一行: P T1 T2……Tp (故障節點的個數及編號)
【輸出文件】
S0 S1 S2 (S1<=S2 從節點I到節點J至少有兩條不同路徑)
【輸入輸出樣例】
route.in
5 1 5
0 10 5 0 0
10 0 0 6 20
5 0 0 30 35
0 6 30 0 6
0 20 35 6 0
1 2
route.out
40 22 30
2、每對頂點之間的最短路徑
求圖中每對頂點之間的最短路徑是指把圖中任意兩個頂點vi和vj(i≠j)之間的最短路徑都計算出來。解決此問題有兩種方法:一是分別以圖中的每個頂點為源點共調用n次迪傑斯特拉演算法,此方法的時間復雜性為O(n3);二是採用下面介紹的弗洛伊德(Floyed)演算法,此演算法的時間復雜性仍為O(n3),但比較簡單。 弗洛伊德演算法實際上是一個動態規劃的演算法。從圖的鄰接矩陣開始,按照頂點v1,v2,…,vn的次序,分別以每個頂點vk(1≤k≤n)作為新考慮的中間點,在第k-1次運算Ak-1 (A(0)為原圖的鄰接矩陣G) 的基礎上,求出每對頂點vi到vj的最短路徑長度計算公式為:
Floyd演算法:
proc shortpath_floyd;
begin
for i:=1 to n do for j:=1 to n do
begin
length[i,j]:=cost[i,j];
if length[i,j]<max then path[i,j]:=[i]+[j];
end;
for k:=1 to n do for i:=1 to n do for j:=1 to n do
if length[i,k]+length[k,j]<length[i,j] then
begin
length[i,j]:=length[i,k]+length[k,j];
path[i,j]:=path[i,k]+path[k,j];
end;
end;
其中:cost為鄰接矩陣;
path[i,j]:表示頂點i到j的最短路徑;
length[i,j]:
練習7:Floyd演算法練習
【問題描述】從文件中讀入帶權圖的信息,按Dijkstra演算法根據給定源點求出從源點到該圖中其餘頂點的最短路徑。
【輸入文件】第一行:一個整數L:L=0表示無向圖,L=1表示有向圖;第二行三個整數m、n,分別表示圖的結點數和圖中的邊數。以下n行表示n條邊:每一行三個數x、y和z,z表示x與y之間邊的權值。第n+2行:整數R,以下R行每行一個整數表示頂點標號作為源點。
【輸出文件】共R行,每一行的數據表示源點到其餘頂點的距離,按頂點編號由小大輸出,如果沒有路徑,輸出-1。
【示例】輸入:1 輸出:-1 10 50 30 60
6 8 -1 –1 –1 20 30
1 3 10
1 5 30
1 6 100
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60
2
1
5