hdu 1150 二分圖最大匹配最小點覆蓋
阿新 • • 發佈:2019-01-26
題意:
有兩臺機器A和B以及k個需要執行的任務。每臺機器有n,m種不同的模式,而每個任務都恰好能在一臺機器上執行。
機器A上有模式 mode_0, mode_1, …, mode_n-1,機器B上有模式: mode_0, mode_1, … , mode_m-1。
開始的工作模式都是mode_0。每個任務有對應的執行模式,(i, x, y)表示i任務對應的A B機器上的執行模式mode_x, mode_y。
每臺機器上的任務可以按照任意順序執行,但是每臺機器每轉換一次模式需要重啟一次。
合理安排順序,使得機器充氣次數最少。問最少是多少次。
解析:
每次來一個任務就加一條向AB機器模式fr,to的邊,最後的最小點覆蓋即為所求。
這題有個坑點是起始的時候機器的工作模式是0,所以有0模式的就沒必要要加入點集了。。。
樣例你是故意的- -
程式碼:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <set> #include <climits> #include <cassert> #define LL long long using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 100 + 10; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); vector<int> g[maxn]; int fr[maxn]; bool vis[maxn]; int n, m; bool match(int v) { for (int i = 0; i < g[v].size(); i++) { int u = g[v][i]; if (!vis[u]) { vis[u] = true; if (fr[u] == -1 || match(fr[u])) { fr[u] = v; return true; } } } return false; } int hungary() { int ret = 0; memset(fr, -1, sizeof(fr)); for (int i = 1; i < n; i++) { memset(vis, false, sizeof(vis)); if (match(i)) { ret++; } } return ret; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAl int k; while (~scanf("%d", &n) && n) { scanf("%d%d", &m, &k); for (int i = 0; i <= n; i++) { g[i].clear(); } while (k--) { int t, fr, to; scanf("%d%d%d", &t, &fr, &to); if(fr && to) g[fr].push_back(to); } printf("%d\n", hungary()); } return 0; }