hdu 5352 MZL's City 【二分图】

来源:互联网 发布:12315投诉淘宝店铺 编辑:程序博客网 时间:2024/06/05 17:34

题目链接: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 200int 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;}
0 0
原创粉丝点击