Hdu 5352 MZL's City (多重匹配)

题目链接:

  Hdu 5352 MZL‘s City

题目描述:

  有n各节点,m个操作。刚开始的时候节点都是相互独立的,一共有三种操作:

  1:把所有和x在一个连通块内的未重建过的点全部重建。

  2:建立一条双向路(x,y)

  3:又发生了地震,p条路被毁。

  问最后最多有多少个节点被重建,输出重建节点的最小字典序。

解题思路:

  这几天正好在学匹配,但是昨天下午还是没有看出来这个是匹配题目。看了题解扪心自问了自己三次,是不是傻。就是把每个需要重建的节点x拆成k个点,然后对每个拆分后的点和与拆点在同一连通块里面的点建边,然后按照倒序进行匹配,保证字典序最大。

  但是匹配好像要比网络流慢好多,改天还是去学一下新姿势的好。

  1 #include <vector>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 using namespace std;
  7 const int maxn = 205;
  8 const int N = 205*500;
  9 vector <int> G[N];
 10 int ans[maxn*2], p[maxn], used[maxn], vis[maxn];
 11 int n, m, k, num, nu, maps[maxn][maxn];
 12 void dfs (int u)
 13 {//求连通块内的点
 14     vis[u] = 1;
 15     p[num ++] = u;
 16     for (int i=1; i<=n; i++)
 17         if (!vis[i] && maps[u][i])
 18             dfs (i);
 19 }
 20 bool Find (int u)
 21 {
 22     for (int i=0; i<G[u].size(); i++)
 23     {
 24         int v = G[u][i];
 25         if (!vis[v])
 26         {
 27             vis[v] = 1;
 28             if (!used[v] || Find(used[v]))
 29             {
 30                 used[v] = u;
 31                 return true;
 32             }
 33         }
 34     }
 35     return false;
 36 }
 37 int hungry ()
 38 {
 39     int res = 0;
 40     memset (used, 0, sizeof(used));
 41     for (int i=nu-1; i>=0; i--)//倒序求最大匹配
 42         for (int j=i*k; j<(i+1)*k; j++)
 43         {
 44             memset (vis, 0, sizeof(vis));
 45             if (Find(j))
 46             {
 47                 res ++;
 48                 ans[i] ++;
 49             }
 50         }
 51     return res;
 52 }
 53 int main ()
 54 {
 55     int t;
 56     scanf ("%d", &t);
 57     while (t --)
 58     {
 59         scanf ("%d %d %d", &n, &m, &k);
 60         memset (maps, 0, sizeof(maps));
 61         for (int i=0; i<N; i++)
 62             G[i].clear();
 63         nu = 0;
 64         while (m --)
 65         {
 66             int type, x, y, z;
 67             scanf ("%d", &type);
 68             if (type == 1)
 69             {
 70                 scanf ("%d", &x);
 71                 num = 0;
 72                 memset (vis, 0, sizeof(vis));
 73                 dfs (x);
 74                 for (int i=0; i<num; i++)//建边
 75                     for (int j=nu*k; j<(nu+1)*k; j++)//拆点
 76                         G[j].push_back(p[i]);
 77                 nu ++;
 78             }
 79             else if (type == 2)
 80             {
 81                 scanf ("%d %d", &x, &y);
 82                 maps[x][y] = maps[y][x] = 1;
 83             }
 84             else
 85             {
 86                 scanf ("%d", &z);
 87                 while (z --)
 88                 {
 89                     scanf ("%d %d", &x, &y);
 90                     maps[x][y] = maps[y][x] = 0;
 91                 }
 92             }
 93         }
 94         memset (ans, 0, sizeof(ans));
 95         int res = hungry ();
 96         printf ("%d\n", res);
 97         for (int i=0; i<nu; i++)
 98             printf ("%d%c", ans[i], i==nu-1?‘\n‘:‘ ‘);
 99     }
100     return 0;
101 }

Hdu 5352 MZL's City (多重匹配)

时间: 2024-10-14 07:21:30

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 【二分图】

题目链接: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 <l

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

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 最小费用最大流

题目链接: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操作给出一

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 8001    Accepted Submission(s): 1758 Problem Description 2012 If this is the end of th

HDU 3605 Escape(二分图多重匹配问题)

Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 10382    Accepted Submission(s): 2485 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient