标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 710 Accepted Submission(s): 245
#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——————【二分图多重匹配、拆点】
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4710039.html