hdu 5352 MZL's City 【二分图】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5352

题意:

给你n,m,k

表示n个建筑 m次操作,修复操作每次最多修复k个建筑。

有三种操作

1.修复x点周围建筑(<=k)

2.x,y建筑间建边

3.x,y间删边

修复建筑时候拆点建图。反着求最大匹配,保证字典序最小。

代码:

#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#pragma comment (linker, "/STACK:102400000,102400000")

using namespace std;

template <class T>
inline bool scan_d(T &ret)
{
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0; //EOF
    while (c != ‘-‘ && (c<‘0‘ || c>‘9‘)) c = getchar();
    sgn = (c == ‘-‘) ? -1 : 1;
    ret = (c == ‘-‘) ? 0 : (c - ‘0‘);
    while (c = getchar(), c >= ‘0‘&&c <= ‘9‘) ret = ret * 10 + (c - ‘0‘);
    ret *= sgn;
    return 1;
}

const int MAXN = 100100;
const int N = 210;
// 200 500 200
int n, m, k;

int mp[N][N];
int book[N];
int match[N];
int path[N];
int len;
int vis[N];
vector<int> g[MAXN];
int ans[N*3], res;
int cc;

void get_path(int u)
{
    vis[u] = 1;
    path[len++] = u;
    for (int i = 1; i <= n; i++)
    {
        if (!vis[i] && mp[u][i] == 1)
        {
            get_path(i);
        }
    }
}

bool dfs(int u)
{
    int i;
    for (i = 0; i < g[u].size(); i++)
    {
        int v = g[u][i];
        if (book[v] == 0)
        {
            book[v] = 1;
            if (match[v] == 0 || dfs(match[v]))
            {
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}

void hungry()
{
    for (int i = cc-1; i >= 0; i--)//保证字典序小 优先匹配后面的
    {
        for (int j = i*k; j < i*k + k; j++)
        {
            memset(book, 0, sizeof(book));
            if (dfs(j))
                ans[i]++;
        }
        res += ans[i];
    }
}

void init()
{
    cc = 0;
    res = 0;
    for (int i = 0; i < 100010; i++) g[i].clear();
    memset(mp, 0, sizeof(mp));
    memset(match, 0, sizeof(match));
    memset(ans, 0, sizeof(ans));
}

int main()
{
    int t;
    scan_d(t);
    while (t--)
    {
        scan_d(n);
        scan_d(m);
        scan_d(k);
        init();
        while(m--)
        {
            int p, q;
            int x, y;
            scan_d(p);
            if (p == 1)
            {
                scan_d(x);
                memset(vis, 0, sizeof(vis));
                len = 0;
                get_path(x);
                for (int i = 0; i < len; i++)
                {
                    for (int j = cc*k; j < (cc + 1)*k; j++)
                        g[j].push_back(path[i]);
                }
                cc++;
            }
            else if (p == 2)
            {
                scan_d(x);
                scan_d(y);
                mp[x][y] = mp[y][x] = 1;
            }
            else if (p == 3)
            {
                scan_d(q);
                while (q--)
                {
                    scan_d(x);
                    scan_d(y);
                    mp[x][y] = mp[y][x] = 0;
                }
            }
        }

        hungry();
        printf("%d\n", res);
        for (int i = 0; i < cc - 1; i++)
            printf("%d ", ans[i]); printf("%d\n", ans[cc - 1]);

    }
    return 0;
}

版权声明:转载请注明出处。

hdu 5352 MZL's City 【二分图】

时间: 2024-10-26 00:06:10

hdu 5352 MZL's City 【二分图】的相关文章

HDU 5352——MZL&#39;s City——————【二分图多重匹配、拆点】

MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 710    Accepted Submission(s): 245 Problem Description MZL is an active girl who has her own country. Her big country has N cities numb

HDU 5352 MZL&#39;s City

最小费用最大流,因为要控制字典序,网络流控制不好了...一直WA,所以用了费用流,时间早的费用大,时间晚的费用少. 构图: 建立一个超级源点和超级汇点.超级源点连向1操作,容量为K,费用为COST,然后COST-1,因为下一次遇到1操作,费用为减少1,即COST-1: 每个1操作连向当前能建造的城市,容量为1,费用为0: 每个城市连向汇点,容量为1,费用为0: #include<cstdio> #include<cstring> #include<cmath> #inc

HDU 5352 MZL&#39;s City(2015 多校 第5场,最小费用最大流)

  MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 291    Accepted Submission(s): 94 Problem Description MZL is an active girl who has her own country. Her big country has N cities nu

Hdu 5352 MZL&#39;s City (多重匹配)

题目链接: Hdu 5352 MZL's City 题目描述: 有n各节点,m个操作.刚开始的时候节点都是相互独立的,一共有三种操作: 1:把所有和x在一个连通块内的未重建过的点全部重建. 2:建立一条双向路(x,y) 3:又发生了地震,p条路被毁. 问最后最多有多少个节点被重建,输出重建节点的最小字典序. 解题思路: 这几天正好在学匹配,但是昨天下午还是没有看出来这个是匹配题目.看了题解扪心自问了自己三次,是不是傻.就是把每个需要重建的节点x拆成k个点,然后对每个拆分后的点和与拆点在同一连通块

hdu 5352 MZL&#39;s City 最小费用最大流

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5352 题意:M年前有一个国家发生了地震.所有城市和城市之间的路都被摧毁了.现在要重建城市. 给出一个N表示共有N个城市,M表示大地震发生在M年前,K表示每次最多只能重建K个城市. 现在从大地震发生的那年开始,每年可以进行一个操作,也就是总共有M个操作. 1 x表示可以重建和x联通(直接或间接)的城市(包括x本身),每次最多只能重建K个城市 2 x y 表示修建了一条城市x到城市y的路. 3操作给出一

HDOJ 5352 MZL&#39;s City 匈牙利匹配

求年份和城市的匹配 MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 539    Accepted Submission(s): 180 Problem Description MZL is an active girl who has her own country. Her big country has N

MZL&#39;s City (hdu 5352 最小费用流 ||二分图匹配)

MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 719    Accepted Submission(s): 251 Problem Description MZL is an active girl who has her own country. Her big country has N cities num

HDU 5344 MZL&#39;s xor (多校)[补7月28]

MZL's xor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 187 Problem Description MZL loves xor very much.Now he gets an array A.The length of A is n.He wants to k

hdu 5348 MZL&amp;#39;s endless loop

给一个无向图(事实上是有向的.可是没有指定边的方向),你须要指定边的方向,使得每一个点入度和出度相差不超过1. 事实上就是找很多条路径.合起来能走完这个图..先统计各个顶点的度.度为奇数必是起点或终点,否则是中间点或者同为起点和终点. 邻接表建图(建双向),先从每一个奇数度顶点出发找路径,再从偶数度顶点出发找路径.经过的边要删去不然超时. #include <iostream> #include <cstring> #include <cstdio> #include