Codeforces 题目传送门 & 洛谷题目传送门

首先我们将所有十进制下位数相同的点看作一种颜色,这样题目转化为,给定 \(m\le 6\) 种颜色、每种颜色的点的个数 \(b_i\) 以及每两种颜色之间连的边的条数 \(c_{i,j}\),要求构造出一棵符合要求的树。

考虑怎样解决上面的问题,这里有一个结论,对于每种颜色我们钦定一个点为“关键点”(方便起见,对于颜色 \(i\),我们钦定 \(10^{i-1}\) 为第 \(i\) 种颜色的关键点),那么,如果存在合法的树,一定存在一种情况,使得任意一条边都有一个点为关键点。至于证明,不太会严谨证明,不过大概想想应该可以想通,大概就是对于每条边 \((u,v)\),如果 \(u,v\) 都不是关键点,那么可以将 \(u\) 改接到 \(v\) 的颜色的关键点,或者将 \(v\) 改接到 \(u\) 的颜色的关键点,总能找到一种调整方法使得不存在 \(u,v\) 都不是关键点的边 \((u,v)\)。

不难发现对于符合上面的条件的图,如果只考虑 \(m\) 个关键点,那么这 \(m\) 个点形成的图也是一棵 \(m\) 个点的树,由于 \(m\) 很小,因此考虑根据 prufer 序列将这 \(m^{m-2}\) 棵树枚举一遍,接下来考虑怎样检验对于一棵关键点的生成树,是否存在一种将非关键点连向关键点的方案,使得对于任意两种颜色 \(i,j\),\(i,j\) 之间连的边数恰为 \(c_{i,j}\),我们不妨将这个问题转化一下,可以得到如下的模型:

  • 对于每种颜色,共有 \(b_i-1\) 个非关键点,对于这 \(b_i-1\) 个关键点中的每一个点 \(u\),我们都要选择一种颜色 \(j\),并将 \(u\) 连向 \(j\) 的关键点,这样会使得 \(u,j\) 间边的个数多 \(1\)。
  • 对于每个颜色之间的二元组 \((i,j)\) 都还需连 \(a_{i,j}\) 条边,其中 \(a_{i,j}\) 为 \(c_{i,j}\) 减去 \(i,j\) 在枚举的生成树上是否存在边。

敏感的同学应该可以发现,这不就一个二分图多重匹配吗?我们将所有颜色对 \((i,j)\) 看作左部点,连一条从源点像这样的 \((i,j)\),容量为 \(a_{i,j}\) 的边,所有颜色 \(i\) 看作右部点,连一条从 \(i\) 到汇点,容量为 \(b_i-1\) 的边,然后检验这张图是否存在完备匹配即可。输出方案就 dinic 跑遍最大流即可。时间复杂度 \(\mathcal O(\text{能过})\)。

const int MAXV=30;
const int MAXE=300*2;
const int INF=0x3f3f3f3f;
int n,m,p[8],q[8],cnt[8];
int S=29,T=30,hd[MAXV+5],to[MAXE+5],nxt[MAXE+5],cap[MAXE+5],ec=1;
void init(){memset(hd,0,sizeof(hd));ec=1;}
void adde(int u,int v,int f){
to[++ec]=v;cap[ec]=f;nxt[ec]=hd[u];hd[u]=ec;
to[++ec]=u;cap[ec]=0;nxt[ec]=hd[v];hd[v]=ec;
} int dep[MAXV+5],now[MAXV+5];
bool getdep(){
memset(dep,-1,sizeof(dep));dep[S]=0;
queue<int> q;q.push(S);now[S]=hd[S];
while(!q.empty()){
int x=q.front();q.pop();
for(int e=hd[x];e;e=nxt[e]){
int y=to[e],z=cap[e];
if(!~dep[y]&&z){
dep[y]=dep[x]+1;
q.push(y);now[y]=hd[y];
}
}
} return ~dep[T];
}
int getflow(int x,int f){
if(x==T) return f;int ret=0;
for(int &e=now[x];e;e=nxt[e]){
int y=to[e],z=cap[e];
if(dep[y]==dep[x]+1&&z){
int w=getflow(y,min(f-ret,z));
cap[e]-=w;cap[e^1]+=w;ret+=w;
if(ret==f) return ret;
}
} return ret;
}
int dinic(){
int ret=0;
while(getdep()) ret+=getflow(S,INF);
return ret;
}
int num[8][8],cc[8][8],pru[8],deg[8],vis[8];
void solve(){
memset(deg,0,sizeof(deg));
memset(vis,0,sizeof(vis));
memset(cc,0,sizeof(cc));
for(int i=1;i<=m-2;i++) deg[pru[i]]++;
for(int i=1;i<=m-2;i++){
int pos=0;
for(int j=1;j<=m;j++){
if(!deg[j]&&!vis[j]){pos=j;break;}
} cc[min(pos,pru[i])][max(pos,pru[i])]++;
// eprintf("%d %d\n",pos,pru[i]);
deg[pru[i]]--;vis[pos]=1;
} int u1=1,u2=m;
while(vis[u1]) u1++;
while(vis[u2]) u2--;
cc[u1][u2]++;
// eprintf("%d %d\n",u1,u2);
int cur=0;init();
for(int i=1;i<=m;i++) for(int j=i;j<=m;j++){
if(cc[i][j]>num[i][j]) return;cur++;
adde(S,cur,num[i][j]-cc[i][j]);
adde(cur,m*(m+1)/2+i,INF);
adde(cur,m*(m+1)/2+j,INF);
} for(int i=1;i<=m;i++) adde(m*(m+1)/2+i,T,cnt[i]-1);
if(dinic()==n-m){
for(int i=1;i<=m;i++) for(int j=i;j<=m;j++){
if(cc[i][j]) printf("%d %d\n",p[i],p[j]);
}
for(int i=1;i<=m;i++) q[i]=p[i];cur=0;
for(int i=1;i<=m;i++) for(int j=i;j<=m;j++){
cur++;
for(int e=hd[cur];e;e=nxt[e]){
int y=to[e],z=cap[e^1];
if(y==S) continue;
if(y-m*(m+1)/2==i){
while(z--) printf("%d %d\n",++q[i],p[j]);
} else {
while(z--) printf("%d %d\n",++q[j],p[i]);
}
}
}
exit(0);
}
}
void dfs(int x){
if(x==m-1) return solve();
for(int i=1;i<=m;i++) pru[x]=i,dfs(x+1);
}
int main(){
scanf("%d",&n);for(int cur=1;cur<=n;cur*=10) p[++m]=cur;
for(int i=1;i<m;i++) cnt[i]=p[i+1]-p[i];cnt[m]=n-p[m]+1;
for(int i=1;i<n;i++){
static char s1[9],s2[9];
scanf("%s%s",s1+1,s2+1);
int l1=strlen(s1+1),l2=strlen(s2+1);
if(l1>l2) l1^=l2^=l1^=l2;
num[l1][l2]++;
} if(m==1){
if(num[1][1]!=n-1) return puts("-1"),0;
for(int i=1;i<n;i++) printf("%d %d\n",i,i+1);
return 0;
} dfs(1);puts("-1");
return 0;
}

Codeforces 611H - New Year and Forgotten Tree(二分图多重匹配)的更多相关文章

  1. hihoCoder 1393 网络流三·二分图多重匹配(Dinic求二分图最大多重匹配)

    #1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小H ...

  2. 【POJ 1698】Alice's Chance(二分图多重匹配)

    http://poj.org/problem?id=1698 电影和日子匹配,电影可以匹配多个日子. 最多有maxw*7个日子. 二分图多重匹配完,检查一下是否每个电影都匹配了要求的日子那么多. #i ...

  3. 稳定的奶牛分配 && 二分图多重匹配+二分答案

    题意: 农夫约翰有N(1<=N<=1000)只奶牛,每只奶牛住在B(1<=B<=20)个奶牛棚中的一个.当然,奶牛棚的容量有限.有些奶牛对它现在住的奶牛棚很满意,有些就不太满意 ...

  4. hiho 第117周 二分图多重匹配,网络流解决

    描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含 ...

  5. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

    [题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个满足要求的组卷算法. ...

  6. POJ2584 T-Shirt Gumbo【二分图多重匹配】

    题目链接: id=2584">http://poj.org/problem?id=2584 题目大意: 如今有5种型号(S.M.L.X.T)的衣服要发放给N个參赛队员.给出每一个參赛者 ...

  7. 网络流24题 第五题 - PowerOJ1740 CodeVS1905 圆桌问题 二分图多重匹配 网络最大流

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - PowerOJ1740 - 有SPJ - 推荐 题目传送门 - CodeVS1905 - 无SPJ - 0% ...

  8. [HihoCoder1393]网络流三·二分图多重匹配

    题目大意: 班级有$N$名学生,运动会有$M$项不同的比赛,第$i$项比赛每个班需要派出$m_i$名选手参加,编号为i的学生最多同时参加给定的$b_i$项比赛中的任意$a_i$项比赛.根据统计的结果, ...

  9. hdu3605 Escape 二分图多重匹配/最大流

    2012 If this is the end of the world how to do? I do not know how. But now scientists have found tha ...

随机推荐

  1. Less-32 宽字节

    <!-- 下午整了半天Less-29~31,愣是没调好jsp环境,只好跳过. 难受.jpg !--> Less-32: 核心语句: 各种回显均存在. 第一句话指定了字符集为gbk. che ...

  2. [敏捷软工团队博客]Beta阶段测试报告

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 博客园班级博客 作业要求 Beta阶段测试报告 我们在这个课程的目标是 在团队合作中锻炼自己 这个作业在哪个具体方面帮助我们实现目标 对Bet ...

  3. 基于JWT的Token身份验证

    ​ 身份验证,是指通过一定的手段,完成对用户身份的确认.为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie.session和token. 1.Cookie ​ cookie是 ...

  4. UltraSoft - Beta - Scrum Meeting 12

    Date: May 28th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 会议记录修复了课程中心导入作业时出现重复的问题完成了消息中心界面的交互 Liuzh ...

  5. 将manjaro作为主力开发系统,我遇到了哪些坑。

    首先遇到的问题就是企业微信. 最开始几天,我直接去安装企业微信和微信,安装全都报错了. 无奈之下,只好安装了virtual box,装了一个win7,可以正常使用微信,企业微信,最开始蛋疼的地方是,企 ...

  6. VS2019、Qt5.12及QGis3.16开发常见问题汇总

    在C++.Qt软件开发过程中,常常遇到一些编译错误或警告:本文将VS2019.Qt5.12.10和QGis3.16.10的二次开发过程常见的问题做了整理,供大家参考,也便于日后查阅.该内容分为四部分: ...

  7. 嵌入式单片机之stm32串口你懂了多少!!

    stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...

  8. 平衡二叉树检查 牛客网 程序员面试金典 C++ Python

    平衡二叉树检查 牛客网 程序员面试金典 C++ Python 题目描述 实现一个函数,检查二叉树是否平衡,平衡的定义如下,对于树中的任意一个结点,其两颗子树的高度差不超过1. 给定指向树根结点的指针T ...

  9. docker+nginx搭建tomcat集群(附录)——nginx.conf文件

    附录:nginx.conf修改后的文件内容 user root;worker_processes 2; #error_log logs/error.log;#error_log logs/error. ...

  10. ACL实验

    ACL实验 基本配置:略 首先根据题目策略的需求1,从这个角度看,我们需要做一条高级ACL,因为我们不仅要看你是谁,还要看你去干什么事情,用高级ACL来做的话,对于我们华为设备,只写拒绝,因为华为默认 ...