圖論基本算法(二)

拓樸排序

因為問題難以描述,直接來看例題ㄅ~

想法:

記錄這些東西:

*目前可以走訪(沒有或以走訪先行處室)的處室

*每個處室的"先行處室數"

*每個處室有哪些"後續處室"

迴圈執行:

*走訪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