HDU 5352——MZL'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 numbered from 1 to N.She has controled the country for so long and she only remebered that there was a big earthquake M years ago,which made all the roads between the cities destroyed and all the city became broken.She also remebered that exactly one of the following things happened every recent M years:

1.She rebuild some cities that are connected with X directly and indirectly.Notice that if a city was rebuilt that it will never be broken again.

2.There is a bidirectional road between city X and city Y built.

3.There is a earthquake happened and some roads were destroyed.

She forgot the exactly cities that were rebuilt,but she only knew that no more than K cities were rebuilt in one year.Now she only want to know the maximal number of cities that could be rebuilt.At the same time she want you to tell her the smallest lexicographically plan under the best answer.Notice that 8 2 1 is smaller than 10 0 1.

Input

The first contains one integer T(T<=50),indicating the number of tests.

For each test,the first line contains three integers N,M,K(N<=200,M<=500,K<=200),indicating the number of MZL’s country ,the years happened a big earthquake and the limit of the rebuild.Next M lines,each line contains a operation,and the format is “1 x” , “2 x y”,or a operation of type 3.

If it’s type 3,first it is a interger p,indicating the number of the destoyed roads,next 2*p numbers,describing the p destoyed roads as (x,y).It’s guaranteed in any time there is no more than 1 road between every two cities and the road destoyed must exist in that time.

Output

The First line Ans is the maximal number of the city rebuilt,the second line is a array of length of tot describing the plan you give(tot is the number of the operation of type 1).

Sample Input

1

5 6 2

2 1 2

2 1 3

1 1

1 2

3 1 1 2

1 2

Sample Output

3

0 2 1

Hint

No city was rebuilt in the third year,city 1 and city 3 were rebuilt in the fourth year,and city 2 was rebuilt in the sixth year.

题目大意:有n个城市,地震后需要重建,m表示有m个操作,k表示重建时最多修k座城市。有三种操作:1:修建跟x连通的城市  2:修一条a、b城市之间的路。 3:c表示地震震坏了c条路,ai、bi之间的路。问怎么重建可以重建最多的城市,且让重建时城市的数量形成的字典序最小

解题思路:其实就是保证在匹配最大时,字典序最小。对于这种一个点可以多次匹配的问题,我们可以把点拆成k个。然后让这k个拆点跟没拆时该点应连的点分别连边。那么就形成了普通的匹配问题。要求的字典序最小,我们可以逆序跑匈牙利,然后顺序输出即可保证字典序最小,因为能匹配的在开始就尽可能多得匹配了,不能匹配的留到最后匹配。

#include<bits/stdc++.h>
using namespace std;
const int maxn=550;
int Map[maxn][maxn];
int vis[maxn],parent[maxn];
int match[maxn],ans[maxn];
vector<int>G[maxn*maxn];
int num,N,divp,K;
void dfs(int u){    //找出跟要重建城市x的所有连通的城市
    vis[u]=1;
    parent[num++]=u;    //记录所有连通城市编号
    for(int i=1;i<=N;i++){
        if(!vis[i]&&Map[u][i]){
            dfs(i);
        }
    }
}
bool Find(int u){   //找增广路
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(!vis[v]){
            vis[v]=1;
            if(!match[v]||Find(match[v])){
                match[v]=u;
                return true;
            }
        }
    }
    return false;
}
int Hungary(){  //匈牙利
    int ret=0;
    memset(ans,0,sizeof(ans));
    memset(match,0,sizeof(match));
    for(int i=divp-1;i>=0;i--){ //逆序跑匈牙利
        for(int j=i*K;j<(i+1)*K;j++){
            memset(vis,0,sizeof(vis));
            if(Find(j)){
                ret++;
                ans[i]++;
            }
        }
    }
    return ret;
}
int main(){
    int t,a,b,c,M,type,res;
    scanf("%d",&t);
    while(t--){
        memset(Map,0,sizeof(Map));
        num=0,divp=0;
        scanf("%d%d%d",&N,&M,&K);
        for(int i=0;i<M;i++){
            scanf("%d",&type);
            if(type==1){
                num=0;
                memset(vis,0,sizeof(vis));
                scanf("%d",&a);
                dfs(a);
                for(int i=0;i<num;i++){ //跟要重建的城市连通的总城市数量
                    for(int j=K*divp;j<K*(divp+1);j++){//拆点
                        G[j].push_back(parent[i]);  //从拆点向要重建的城市连边
                    }
                }
                divp++;
            }else if(type==2){
                scanf("%d%d",&a,&b);
                Map[a][b]=Map[b][a]=1;
            }else{
                scanf("%d",&c);
                for(int j=0;j<c;j++){
                    scanf("%d%d",&a,&b);
                    Map[a][b]=Map[b][a]=0;
                }
            }
        }
        res=Hungary();
        printf("%d\n",res);
        for(int i=0;i<divp;i++){    //顺序输出
            printf("%d%c",ans[i],i==divp-1?‘\n‘:‘ ‘);
        }
        for(int i=0;i<=K*divp+K;i++){
            G[i].clear();
        }
    }
    return 0;
}

  

HDU 5352——MZL's City——————【二分图多重匹配、拆点】

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

HDU 5352——MZL's City——————【二分图多重匹配、拆点】的相关文章

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 题意: 给你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

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操作给出一

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 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 (二分图多重匹配)

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

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