1. 程式人生 > >洛谷P3386 【模板】二分圖匹配

洛谷P3386 【模板】二分圖匹配

題目背景

二分圖

感謝@一扶蘇一 提供的hack資料

題目描述

給定一個二分圖,結點個數分別為n,m,邊數為e,求二分圖最大匹配數

輸入輸出格式

輸入格式:

 

第一行,n,m,e

第二至e+1行,每行兩個正整數u,v,表示u,v有一條連邊

 

輸出格式:

 

共一行,二分圖最大匹配

 

輸入輸出樣例

輸入樣例#1:  複製
1 1 1
1 1
輸出樣例#1:  複製
1

說明

n,m1000, 1un, 1vm

因為資料有坑,可能會遇到 v>m 的情況。請把 v>m 的資料自覺過濾掉。

演算法:二分圖匹配

 

/*
    二分圖匈牙利演算法模板 沒什麼可說的
*/

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e3+5;

inline int read() {
     int x = 0,m = 1;
     char ch;
     while(ch < '0' || ch > '9')  {if(ch == '-') m = -1;ch = getchar();}
     while(ch >= '0' && ch <= '
9'){x = x * 10 + ch-'0';ch = getchar();} return m * x; }//快讀 vector<int> G[maxn];//vector存圖 效率比前向星慢 但是好寫 int link[maxn],vis[maxn],n,m,e; bool dfs(int x){ for(int i = 0;i < G[x].size();i++){ int v = G[x][i]; if(!vis[v]){ vis[v] = 1;//記住要對這個陣列置1不然會爆空間23333
if(!link[v] || dfs(link[v])){ link[v] = x;return true;//匈牙利演算法核心程式碼 } } } return false; } int main() { int x,y; n = read(),m = read(),e = read(); for(int i = 1;i <= e;i++){ x = read(),y = read(); if(x <= n && y <= m) G[x].push_back(y);//記得過濾掉不合法的狀態 } int ans = 0; for(int i = 1;i <= n;i++){ memset(vis,0,sizeof(vis));//這裡一定要記得memset if(dfs(i)) ans++; } printf("%d\n",ans); return 0; }