poj 2594 Treasure Exploration (floyd傳遞閉包+最小路徑覆蓋)
阿新 • • 發佈:2018-12-18
這道題為有向圖有相交邊的情況。。不能直接求最大匹配
先用floyd處理一下邊
// // main.cpp // wzazzy // // Created by apple on 2018/10/23. // Copyright © 2018年 apple. All rights reserved. // #include<stdio.h> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<string.h> #include<queue> #include<stack> #include<list> #include<map> #include<set> #include<vector> using namespace std; typedef long long int ll; const int maxn =1500+10; const int maxm=10000; const int mod =1e9+7; const int INF=0x3f3f3f3f; //********************************** int n, m, maze[510][510], linker[510]; bool used[510]; void Floyd(){ for(int k = 1; k <= n; ++k) for(int i = 1; i <= n; ++i) if(maze[i][k]){ for(int j = 1; j <= n; ++j) if(maze[k][j]) maze[i][j] = 1; } } bool dfs(int u){ for(int v = 1; v <= n; ++v){ if(maze[u][v] && !used[v]){ used[v] = true; if(linker[v] == -1 || dfs(linker[v])){ linker[v] = u; return true; } } } return false; } int hungary(){ int res = 0; memset(linker, -1, sizeof(linker)); for(int i = 1; i <= n; ++i){ memset(used, false, sizeof(used)); if(dfs(i)) ++res; } return res; } int main() { while(~scanf("%d%d", &n, &m) && (n||m)){ memset(maze, 0, sizeof(maze)); int u, v; for(int i = 0; i < m; ++i){ scanf("%d%d", &u, &v); maze[u][v] = 1; } Floyd(); int ans = hungary(); printf("%d\n", n-ans); } }