POJ-1422二者間グラフ

トピック

n個のポイントとm個のエッジを持つ有向非周期グラフを作成します。いくつかのパラトルーパーを送って特定のポイントに着陸させ、すべてのポイントを歩きましょう。すべてのパラトルーパーのパスをオーバーラップさせることはできません。つまり、最小のエッジカバレッジを探します。

定理

最小エッジカバレッジ=ポイント数-2分割グラフの最大一致数

分析

各パラトルーパーのパスはオーバーラップできないため、各ポイント
の最大アウトディグリーとインディグリーは1です。すべてのポイントの最大アウトディグリーとインディグリーが1になるように、いくつかのエッジを選択するように問題を単純化します。
エッジを追加するためあなたはパラトルーパーを救うことができるので、答え=ポイント-選択された側の数

アウトディグリーとインディグリーは1または0のみであるため、2部グラフの一致および不一致に対応できます。
したがって、各ポイントのアウトディグリーとインディグリーを2つのセットに分けます。2つのセットで2分割グラフマッチングを実行できます。一致したエッジは、グラフで選択されたエッジです。

ACコード

#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 200;
const int inf = 1e9;
#define fast ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);

int G[maxn][maxn];
int vis[maxn], match[maxn];

int n, m;
int find(int x){
    
    
	for(int i = 1 ; i <= n ; i++){
    
    
		if(G[x][i] && !vis[i]){
    
    
			vis[i] = 1;
			if(match[i] == 0 || find(match[i])){
    
    
				match[i] = x;
				return 1;
			}
		}
	}
	return 0;
}

int main(){
    
    
	int T;
	cin >> T;
	while(T--){
    
    
		cin >> n >> m;

		memset(G, 0, sizeof G);
		memset(match, 0, sizeof match);
		int l, r;
		for(int i = 1 ; i <= m ; i++){
    
    
			cin >> l >> r;
			G[l][r] = 1;					
		}
		
		int ans = n;
		for(int i = 1 ; i <= n ; i++){
    
    
			for(int j = 1 ; j <= n ; j++)vis[j] = 0;
			ans -= find(i);
		}
		cout << ans << endl;
	}
}

おすすめ

転載: blog.csdn.net/qq_35068676/article/details/109629801