圖論基本算法(二)
拓樸排序
因為問題難以描述,直接來看例題ㄅ~
想法:
記錄這些東西:
*目前可以走訪(沒有或以走訪先行處室)的處室
*每個處室的"先行處室數"
*每個處室有哪些"後續處室"
迴圈執行:
*走訪queue裡的處室
*把該處室所有的後續流程處室的"先行程序數"-1
*若發現有"先行程序數"為0的處室,則將其加到queue中。
4
3
2
5
1
#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int> mapa[100010];
int degree[100010];
queue<int> cango;
vector<int> ans;
bool check(){
for (int i=1;i<=n;i++){
if (degree[i]){
return 0;
}
}
return 1;
}
int main(){
cin>>n>>m;
int a,b;
for (int i=0;i<m;i++){
cin>>a>>b;
mapa[a].push_back(b);
degree[b]++;
}
for (int i=1;i<=n;i++){
if (!degree[i]){
cango.push(i);
}
}
int from;
while (cango.size()){
from=cango.front();cango.pop();
ans.push_back(from);
for (int x:mapa[from]){
degree[x]--;
if (!degree[x]){
cango.push(x);
}
}
}
if (check()){
cout<<"YES\n";
for (int i=0;i<n;i++){
cout<<ans[i]<<'\n';
}
}else {
cout<<"NO\n";
}
return 0;
}
code:
K筆畫問題
給一圖
(無須連通,有向或無向都可以,做法不同但差不多),求最少可用幾條不交集的路徑遍歷完所有邊。
想法(無向圖):
先用DFS遍歷每個連通塊
對於每個連通塊,數有幾個"度數為奇數的點",
其路徑數為"度數為奇數的點"的個數/2
(可以證明"度數為奇數的點"的個數恆為偶數)
真的是這樣嗎?
若"度數為奇數的點"的個數為0:
case1:該連通塊是一孤點:沒有路徑。
case2:該連通塊是一迴路:有1條路徑。
#include <bits/stdc++.h>
using namespace std;
vector<int> mapa[100010];
int wed[100010];
int cnth;
void DFS(int I){
int sizea=mapa[I].size();
wed[I]=1;
cnth+=sizea%2;
for (int i=0;i<sizea;i++){
if (!wed[mapa[I][i]]){
DFS(mapa[I][i]);
}
}
}
int main(){
int A,B,S,M,K,a,b,w,ans=0;
cin>>A>>B>>S>>M>>K;
for (int i=0;i<K;i++){
cin>>a>>b>>w;
mapa[a].push_back(A+b);
mapa[A+b].push_back(a);
}
memset(wed,0,sizeof(wed));
for (int i=1;i<=A+B;i++){
if (!wed[i]&&mapa[i].size()){
cnth=0;
DFS(i);
if (cnth==0){
ans++;
}
ans+=cnth/2;
}
}
cout<<ans;
return 0;
}
code:
例題:
圖論基本算法(二)
By jeffreylin0909
圖論基本算法(二)
- 113