zoukankan      html  css  js  c++  java
  • CodeForce 387D. George and Interesting Graph

    题目链接

    https://codeforces.com/problemset/problem/387/D

    题意

    思路

    (N)不大,考虑枚举中心点(u), 首先和(u)相连的边加上自环共有(2 * n - 1)条, 那么将不够的边补上。
    每个边都和(u)有双向边之后, 入度和出度还剩1.
    将剩下(n - 1) 个点拆成入度点和出度点, 那么每个点的入度和出度必须有连边, 那么将原图建成二分图跑最大匹配后将多余边删去,不足的补上即可。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn = 2000 + 50;
    vector<int> G[maxn];
    int match[maxn], used[maxn];
    int tot;
    void add(int u, int v){
        G[u].push_back(v);
        G[v].push_back(u);
    }
    bool dfs(int v){
        used[v] = 1;
        for(int i = 0;i < G[v].size();i++){
            int u = G[v][i];
            int w = match[u];
            if(w < 0 || !used[w] && dfs(w)){
                match[v] = u;
                match[u] = v;
                return true;
            }
        }
        return false;
    }
    int max_matching(){
        int ans = 0;
        memset(match, -1, sizeof(match));
        for(int i = 1;i <= tot;i++){
            if(match[i] < 0){
                memset(used, 0, sizeof(used));
                if(dfs(i)) ans++;
            }
        }
        return ans;
    }
    int n, m;
    int mp[maxn][maxn];
    int u[maxn], v[maxn];
    int main()
    {
        std::ios::sync_with_stdio(false);
        cin >> n >> m;
        for(int i = 1;i <= m;i++){
            cin >> u[i] >> v[i];
            mp[u[i]][v[i]] = 1;
        }
        int ans = 0x3f3f3f3f;
        tot = 2 * n;
        for(int i = 1;i <= n;i++){
            int sum = 0;
            for(int j = 1;j <= n;j++){
                if(!mp[i][j]) sum++;
                if(i != j && !mp[j][i]) sum++;
            }
            int cnt = m - (2 * n - 1 - sum);
            for(int i = 0;i <= tot;i++) G[i].clear();
            for(int j = 1;j <= m;j++){
                int a = u[j], b = v[j];
                if(a != i && b != i){
                    add(a, b + n);
                }
            }
            int c = max_matching();
            sum += cnt - c;
            cnt = 0;
            for(int j = 1;j <= 2 * n;j++){
                if(match[j] == -1 && j != i && j != i + n){
                    cnt++;
                }
            }
            ans = min(ans, sum + cnt / 2);
        }
        cout << ans << endl;
    
        return 0;
    }
    
    
  • 相关阅读:
    Redis(01)基础知识
    MySQL(05)触发器&事件&事务&锁
    MySQL(04)索引&存储过程
    MySQL(02)DDL&DML
    MySQL(03)表查询
    Go高级编程(01)
    兼容IE8灰色遮罩层处理方法
    AJAX请求跨域的问题
    Sql Server批量删除数据表
    [转]SQL操作日期
  • 原文地址:https://www.cnblogs.com/Carered/p/14100764.html
Copyright © 2011-2022 走看看