把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

noi.ac-CSP模拟Day5T1 组【二分图最大匹配】

 

 

虽然是T3,但是想通了之后还是不难的。

数据规模也不大。

可以考虑先枚举一个班长,根据题意,和班长连边的学生就可以不用管,没有和班长连边的学生就要去找一个和班长连边的学生组队,如果所有没有和班长连边的学生都能找到一个人组队,就可以。

是一个比较裸的二分图最大匹配。

注意要重新建图,不能直接在原来的图上跑,因为有可能和班长连边的学生之间存在彼此连边的情况,就不符合二分图的定义。

可以另建图跑最大流,也可以就匈牙利,或者EK

复制代码
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<string>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<cstdlib>
 9 using namespace std;
10 #define N 1005
11 #define ll long long 
12 #define INF 0x3f3f3f3f
13 int n,m;
14 vector<int>G[N],T[N];
15 bool vis[N],flag[N];
16 int mch[N];
17 bool dfs(int u)
18 {
19     for(int i=0;i<T[u].size();i++)
20     {
21         int v=T[u][i];
22         if(vis[v]) continue;
23         vis[v]=1;
24         if(mch[v]==0||dfs(mch[v]))
25         {
26             mch[v]=u;
27             mch[u]=v;
28             return 1;
29         }
30     }
31     return 0;
32 }
33 int main()
34 {
35     scanf("%d %d",&n,&m);
36     for(int i=1;i<=m;i++)
37     {
38         int u,v;scanf("%d %d",&u,&v);
39         G[u].push_back(v);
40         G[v].push_back(u);
41     }
42     for(int s=1;s<=n;s++)//枚举班长
43     {
44         if(G[s].size()<((n-1)/2)) continue;//如果班长连的学生太少 
45         int res=0,num=n-G[s].size()-1/*还有一个自己*/;
46         for(int i=1;i<=n;i++)
47             T[i].clear(),flag[i]=0/*标记是否与班长相连*/,mch[i]=0;
48         mch[s]=-1,flag[s]=1/*防止班长被建到图里面去*/;
49         for(int i=0;i<G[s].size();i++)
50             flag[G[s][i]]=1;
51         for(int i=0;i<G[s].size();i++)
52         {
53             int v=G[s][i];
54             for(int j=0;j<G[v].size();j++)
55                 if(!flag[G[v][j]])
56                     T[v].push_back(G[v][j]);
57         }
58         for(int i=0;i<G[s].size();i++)
59         {
60             memset(vis,0,sizeof(vis));
61             if(dfs(G[s][i]))
62                 res++;
63         }
64         if(res>=num)
65         {
66             puts("Yes");
67             for(int i=1;i<n;i++)
68                 printf("%d ",mch[i]);
69             printf("%d\n",mch[n]);
70             return 0;
71         }
72     }
73     puts("No");
74     return 0;
75 }
Code
复制代码

 

 

posted @   Starlight_Glimmer  阅读(167)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示