docker容器基本原理及安裝
阿新 • • 發佈:2022-03-24
從上週五開始學縮點,今天終於把程式碼敲過了,再次做一個總結(有好多問題需要總結)。
概念:
縮點:在一張有向圖中,將圖中的強連通分量縮成一個點。
連通分量:一個點集,是的點集中的點兩兩之間可以互相抵達。
強連通分量:這個點集中無法再加入一個新的點。
思路:
1.從一個未搜過的點開始,將這個點標記為正在搜的點,並用另一陣列記錄這個點為第幾個被搜到的點(dfn),把這個點放入棧中。
2.搜這個點能到達的所有的點,並用一個數組記錄它能到的所有的點中dfn最小的一個(low)(能到的所有的點包括未搜的和正在搜的)。
3.在搜完後判斷如果這個點的dfn和low相等說明從棧頂到這個元素屬於同一個強連通分量,並把它們從這個棧中刪掉,將這些點標記為搜完的點。
我在學縮點的期間遇到的一些問題:
1.
從點1開始,先查2,再查3,再查4,又查到1,返回到1,接著查5,返回來dfn[1]是等於low[1]的,所以這是一個強連通分量,但是點1,2,3,4是一個強連通分量,不包括5。
解釋:判斷點1前就已經判斷了點5,而且已經將點5自己判斷為一個強連通分量,出棧了,所以記錄時會將點1,2,3,4記錄為一個強連通分量,點5記錄為一個強連通分量。
2.
我原來的時候一直在一個點搜完後將它標記為搜完,而不是在它出棧時標記,就一直錯。
解釋:根據上面這個圖,點1,2,3,4顯然是一個強連通分量,但是如果在一個點搜完後就立刻將它標記為搜完,點4就不會搜點3了,這樣就會將點4自己標記為一個強連通分量所以要在它出棧時再將它標記為搜完。
下面是程式碼:
點選檢視程式碼
#include<iostream> using namespace std; int n,m; int a[10010]; int head[10010],tot; int shead[10010],stot; struct node{ int to; int nxt; }edge[100010],sedge[100010]; void build(int u,int v){ edge[++tot].to=v; edge[tot].nxt=head[u]; head[u]=tot; } void addedge(int u,int v){ sedge[++stot].to=v; sedge[stot].nxt=shead[u]; shead[u]=stot; } int dfn[10010],low[10010],cnt; int zhen[100010],top; int dian[10010],shu; int dui[10010]; int ru[10010]; int vis[10010]; void dfs(int u){ low[u]=dfn[u]=++cnt; zhen[++top]=u; vis[u]=1; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(dfn[v]==0){ dfs(v); low[u]=min(low[v],low[u]); } else if(vis[v]==1)low[u]=min(low[u],low[v]); } if(low[u]==dfn[u]){ shu++; while(zhen[top]!=u){ vis[zhen[top]]=0; dian[shu]+=a[zhen[top]]; dui[zhen[top]]=shu; top--; } top--; dui[u]=shu; dian[shu]+=a[u]; vis[u]=0; } } int maxn; int f[10010]; void tuopu(int u){ for(int i=shead[u];i;i=sedge[i].nxt){ int v=sedge[i].to; if(f[u]+dian[v]>f[v]){ f[v]=f[u]+dian[v]; maxn=max(maxn,f[v]); tuopu(v); } } } int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=m;i++){ int u,v; cin>>u>>v; build(u,v); } for(int i=1;i<=n;i++){ if(dfn[i]==0){ dfs(i); } } for(int i=1;i<=n;i++){ for(int j=head[i];j;j=edge[j].nxt){ int v=edge[j].to; if(dui[v]!=dui[i]){ addedge(dui[i],dui[v]); ru[dui[v]]++; } } } for(int i=1;i<=shu;i++){ if(ru[i]==0){ f[i]=dian[i]; maxn=max(f[i],maxn); tuopu(i); } } cout<<maxn; return 0; }