# AP325 (圖論) ## DFS深度優先搜尋 ```cpp= #include<bits/stdc++.h> using namespace std; int arr[10000]; void postorder(int n){ if(arr[n]==-1)return; cout<<arr[n]; postorder(2*n+1); postorder(2*n+2); } int main(){ int n; cin>>n; memset(arr, -1, sizeof(arr)); for(int i=0;i<n;i++)cin>>arr[i]; postorder(0); } ``` ## DAG ( 無環有向圖 ) ```cpp= #include<bits/stdc++.h> using namespace std; #define N 20 int main(){ vector<int> adj[N]; int indeg[N]={0}; int n, m; int ans[N]={0}; int cnt=0; cin>>n>>m; for(int i=0;i<m;i++){ int from, to; cin>>from>>to; adj[from].push_back(to); indeg[to]++; } queue<int> q; for(int i=0;i<n;i++){ if(indeg[i]==0){ q.push(i); ans[cnt++]=i; } } while(!q.empty()){ int p=q.front(); q.pop(); for(int i=0;i<adj[p].size();i++){ int x=adj[p][i]; indeg[x]--; if(indeg[x]==0){ q.push(x); ans[cnt++]=x; } } } for(int i=0;i<cnt;i++)cout<<ans[i]<<' '; } ``` ## 鄰接串列 ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ int n, m, s; cin>>n>>m>>s; vector<int> v[105]; queue<int> q; int vis[105]; int cnt=0, sum=0; memset(vis, -1, sizeof(vis)); for(int i=0;i<m;i++){ int from, to; cin>>from>>to; v[from].push_back(to); } q.push(s); vis[s]=0; while(!q.empty()){ int p=q.front(); q.pop(); for(int i=0;i<v[p].size();i++){ int x=v[p][i]; if(vis[x]==-1){ vis[x]=vis[p]+1; q.push(x); cnt++; sum+=vis[x]; } } } cout<<cnt<<'\n'<<sum; } ``` ## 鄰接矩陣 ```cpp= #include<bits/stdc++.h> using namespace std; int n, m, s; int adj[100][100]={0}; int d[100]; void bfs(int s){ bool vis[n]={0}; queue<int> q; q.push(s); d[s]=0; vis[s]=1; int cnt=0, ans=0; while(!q.empty()){ int v=q.front(); q.pop(); for(int i=0;i<n;i++){ if(!vis[i] && adj[v][i]){ q.push(i); d[i]=d[v]+1; ans+=d[i]; vis[i]=1; cnt++; } } } cout<<cnt<<'\n'<<ans; } int main(){ cin>>n>>m>>s; for(int i=0;i<m;i++){ int x, y; cin>>x>>y; adj[x][y]=1; } bfs(s); } ``` ## DAG最長與最短路徑 ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ int n, m, s, t; int cnt=0; int indeg[10000]={0}; vector<pair<int,int>> v[10000]; queue<int> q; int maxw[10000], minw[10000]; cin>>n>>m>>s>>t; for(int i=0;i<m;i++){ int from, to, w; cin>>from>>to>>w; v[from].push_back({to,w}); indeg[to]++; } for(int i=0;i<n;i++)maxw[i]=-10000001; for(int i=0;i<n;i++)minw[i]=10000001; maxw[s]=0, minw[s]=0; for(int i=0;i<n;i++){ if(indeg[i]==0){ q.push(i); } } while(!q.empty()){ int p=q.front(); q.pop(), cnt++; for(auto e:v[p]){ if(minw[p]<1000001){ maxw[e.first]=max(maxw[e.first], maxw[p]+e.second); minw[e.first]=min(minw[e.first], minw[p]+e.second); } indeg[e.first]--; if(indeg[e.first]==0){ q.push(e.first); } } } if (cnt!=n) fprintf(stderr, "Not a dag, %d < %d\n", cnt, n); if(minw[t]<10000001)cout<<minw[t]<<'\n'<<maxw[t]; else cout<<"No path"<<'\n'<<"No path"; } ``` ## 最短路徑 ( dijkstra ) ```cpp= #include<bits/stdc++.h> using namespace std; #define MAX 10000005 #define N 100 int main(){ int n, m, w[N][N], parent[N]; cin>>n>>m; for(int i=0;i<n;i++) for(int j=0;j<n;j++) w[i][j]=MAX; for(int i=0;i<m;i++){ int u, v, t; cin>>u>>v>>t; w[u][v]=w[v][u]=min(w[u][v], t); } int d[N], source=0; bool done[N]={0}; for(int i=0;i<n;i++){ d[i]=MAX; parent[i]=-1; } d[source]=0; while(1){ int v=-1, mind=MAX; for(int i=0;i<n;i++){ if(!done[i] && d[i]<mind){ mind=d[i], v=i; } } if(v<0)break; done[v]=1; for(int i=0;i<n;i++){ if(d[v]+w[v][i]<d[i]){ d[i]=d[v]+w[v][i]; parent[i]=v; } } } int maxd=-1, cnt=0, far; for(int i=0;i<n;i++){ if(d[i]<MAX){ if(d[i]>maxd)maxd=d[i], far=i; }else cnt++; } cout<<maxd<<'\n'<<cnt<<'\n'; } ``` ## 最小生成樹 ### prim 演算法 ```cpp= #include<bits/stdc++.h> using namespace std; #define MAX 2147483647 #define N 10005 int main(){ vector<pair<int,int>> v[N]; int n, m; int d[N], done[N]={0}; cin>>n>>m; for(int i=0;i<m;i++){ int from, to, w; cin>>from>>to>>w; v[from].push_back({to,w}); v[to].push_back({from,w}); } for(int i=0;i<n;i++)d[i]=MAX; priority_queue<pair<int,int>> pq; pq.push({d[0]=0, 0}); while(!pq.empty()){ auto p=pq.top(); pq.pop(); if(done[p.second])continue; done[p.second]=1; for(auto e:v[p.second]){ if(done[e.first])continue; if(e.second<d[e.first]){ d[e.first]=e.second; pq.push({-d[e.first], e.first}); } } } int cost=0, cnt=0; for(int i=0;i<n;i++){ if(d[i]<MAX)cost+=d[i]; else cnt++; } if(cnt)cout<<-1<<'\n'; else cout<<cost<<'\n'; } ``` ### kruskal演算法 ```cpp= #include<bits/stdc++.h> using namespace std; int p[10005]; struct EDGE{ int u, v, w; }; int cmp(EDGE &p, EDGE &q){ return p.w<q.w; } int rfind(int n){ if(p[n]<0)return n; return p[n]=rfind(p[n]); } bool joint(int u, int v){ int r1, r2; r1=rfind(u); r2=rfind(v); if(r1==r2)return false; if(r1<r2){ p[r1]+=p[r2]; p[r2]=r1; } else{ p[r2]+=p[r1]; p[r1]=r2; } return true; } int main(){ int n, m; cin>>n>>m; vector<EDGE> edge; for(int i=0;i<m;i++){ int u, v, t; cin>>u>>v>>t; edge.push_back({u, v, t}); } int cost=0, n_edge=0; for(int i=0;i<n;i++)p[i]=-1; sort(edge.begin(), edge.end(), cmp); for(EDGE e:edge){ if(joint(e.u, e.v)){ cost+=e.w; n_edge++; } } if(n_edge<n-1)cout<<-1<<'\n'; else cout<<cost<<'\n'; } ```