hihocoder 1122 没有明确指出两个点集的二分匹配

来源:互联网 发布:windows系统log 编辑:程序博客网 时间:2024/05/25 01:36

传送门
思路:
复制一个点集,加双向边,最大匹配数除以2.

#include<cstring>#include<cstdio>#include<iostream>#include<cmath>#include<algorithm>#include<queue>#include<vector>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;#define LL long long#define INF 0x3f3f3f3fconst int maxn =1005; // 单侧顶点的最大数目// 二分图最大基数匹配struct BPM {  int n, m;               // 左右顶点个数  vector<int> G[maxn];    // 邻接表  int left[maxn];         // left[i]为右边第i个点的匹配点编号,-1表示不存在  bool T[maxn];           // T[i]为右边第i个点是否已标记  int right[maxn];        // 求最小覆盖用  bool S[maxn];           // 求最小覆盖用  void init(int n, int m) {//求匹配前记得初始化。    this->n = n;    this->m = m;    for(int i = 0; i < n; i++) G[i].clear();  }  void AddEdge(int u, int v) {//编号从0开始的,用的时候要减去1,如果从1开始的话    G[u].push_back(v);  }  bool match(int u){    S[u] = true;    for(int i = 0; i < G[u].size(); i++) {      int v = G[u][i];      if (!T[v]){        T[v] = true;        if (left[v] == -1 || match(left[v])){          left[v] = u;          right[u] = v;          return true;        }      }    }    return false;  }  // 求最大匹配  int solve() {    memset(left, -1, sizeof(left));    memset(right, -1, sizeof(right));    int ans = 0;    for(int u = 0; u < n; u++) { // 从左边结点u开始增广      memset(S, 0, sizeof(S));      memset(T, 0, sizeof(T));      if(match(u)) ans++;    }    return ans;  }  // 求最小覆盖。X和Y为最小覆盖中的点集  int mincover(vector<int>& X, vector<int>& Y) {    int ans = solve();    memset(S, 0, sizeof(S));    memset(T, 0, sizeof(T));    for(int u = 0; u < n; u++)      if(right[u] == -1) match(u); // 从所有X未盖点出发增广    for(int u = 0; u < n; u++)      if(!S[u]) X.push_back(u); // X中的未标记点    for(int v = 0; v < m; v++)      if(T[v]) Y.push_back(v);  // Y中的已标记点   return ans;  }};BPM solver;int N,M;int u,v;int vis[maxn];int main(){    scanf("%d%d",&N,&M);    solver.init(N,N);    while(M--){        scanf("%d%d",&u,&v);        u--;v--;        solver.AddEdge(u,v);        solver.AddEdge(v,u);    }    cout<<solver.solve()/2<<endl;    return 0;}
0 0
原创粉丝点击