ContestHunter#17-C 舞动的夜晚
Description:
L公司和H公司举办了一次联谊晚会。晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞。在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的,这样的认识关系一共有T对。舞会上,每位员工会尝试选择一名Ta认识的对方公司的员工作为舞 伴,并且每位员工至多跳一支舞。完成的交际舞的数量越多,晚会的气氛就越热烈。顾及到晚会的气氛,员工们希望知道,哪些员工之间如果进行了交际舞,就会使整场晚会能够完成的交际舞的最大数量减小。
Input
第一行三个整数N、M、T。 接下来T行每行两个整数x、y,表示L公司的员工x和H公司的员工y互相认识。
output
第一行一个整数cnt,表示进行了交际舞后会使整场晚会能够完成的交际舞的最大数量减小的员工有多少对。 第二行cnt个整数,升序输出这样的一对员工的认识关系的编号(他们的认识关系是在输入数据中读入的第几条认识关系)。如果cnt=0,输出一个空行。
思路:判断二分图匹配的可行变与不可行边,就是二分图跑完网络流后,将匹配边所对应的两点加入新的图,然后跑一个tarjan
此时必须边的判定条件为:(x,y)流量为1,并且在残量网络上属于不同的强联通分量。可行边的判断条件为(x,y)的流量为1,或者在残量网络上属于同一个前强联通分量
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int N = , M = , INF = 1e9; int head[N], now = ;
struct edges{
int to,next,w;
}edge[M<<];
void add(int u,int v,int w){ edge[++now].to = v, edge[now].next = head[u], edge[now].w = w; head[u] = now; } int n, m, q, s, t, maxflow, dep[N];
struct input{
int x,y;
}inp[M]; bool bfs(){
memset(dep,,sizeof(dep));
queue<int> q;
q.push(s);
dep[s] = ;
while(!q.empty()){
int x = q.front(); q.pop();
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].w && !dep[v]){
q.push(v);
dep[v] = dep[x] + ;
if(v == t) return ;
}
}
}
return ;
}
int dinic(int x,int flow){
if(x == t) return flow;
int rest = flow, k;
for(int i = head[x]; i && rest; i = edge[i].next){
int v = edge[i].to;
if(edge[i].w && dep[v] == dep[x] + ){
k = dinic(v, min(rest, edge[i].w));
if(!k) dep[v] = ;
edge[i].w -= k;
edge[i ^ ].w += k;
rest -= k;
}
}
return flow - rest;
} vector<int> vec[N], ans;
void add2(int u,int v) { vec[u].push_back(v);}
int dfn[N], low[N], cnt, tot, dict[N];
bool vis[N];
stack<int> sta;
void tarjan(int x){
dfn[x] = low[x] = ++cnt;
sta.push(x); vis[x] = ;
for(int i = ; i < vec[x].size(); i++){
int v = vec[x][i];
if(!dfn[v]){
tarjan(v);
low[x] = min(low[x], low[v]);
}
else if(vis[v]) low[x] = min(low[x], dfn[v]);
}
if(dfn[x] == low[x]){
tot++;
int temp = -;
do{
temp = sta.top(); sta.pop();
vis[temp] = ;
dict[temp] = tot;
}while(temp != x);
}
return ;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m>>q;
int x,y;
for(int i = ; i <= q; i++){ //左部节点为1 ~ n,右部节点为 n ~ n + m
cin>>x>>y;
y += n;
inp[i].x = x, inp[i].y = y;
add(x,y,); add(y,x,);
}
s = , t = n+m+;
for(int i = ; i <= n; i++)
add(s,i,), add(i,s,);
for(int i = n+; i <= n+m; i++)
add(i,t,), add(t,i,);
int tmp = ;
while(bfs())
while(tmp = dinic(s,INF)) maxflow += tmp; //最大流解二分图匹配
for(int i = ; i <= now; i++) //将匹配了的边所对应的两点加入新图
if(edge[i].w) add2(edge[i ^ ].to, edge[i].to);
for(int i = s; i <= t; i++) //tarjan找scc
if(!dfn[i]) tarjan(i);
for(int i = ; i <= q; i++) //关于不可行边的判断条件
if(dict[inp[i].x] != dict[inp[i].y] && edge[i * ].w != )
ans.push_back(i);
int tot = ans.size();
cout<<tot<<endl;
for(int i = ; i < ans.size(); i++){
if(i < tot - ) cout<<ans[i]<<" ";
else cout<<ans[i]<<endl;
}
return ;
}
注意最后空格的输出……不然PE
ContestHunter#17-C 舞动的夜晚的更多相关文章
- CH Round #17 舞动的夜晚
舞动的夜晚 CH Round #17 描述 L公司和H公司举办了一次联谊晚会.晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞.在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的 ...
- [Contest Hunter#17-C] 舞动的夜晚
[题目链接] http://contest-hunter.org:83/contest/CH%20Round%20%2317/%E8%88%9E%E5%8A%A8%E7%9A%84%E5%A4%9C% ...
- CH#17C 舞动的夜晚
原题链接 即求二分图的不可行边数量,因为不保证是完备匹配,所以需要通过网络流求出任意一组最大匹配,并建立新图判断. 建新图:对于跑完网络流的图上已经匹配的边,建立反边:对于没有匹配的边,建立正边(图只 ...
- AcWing 380. 舞动的夜晚
大型补档计划 题目链接 这题是求必须边,而不是不可行边,因为不可行边 = 必须边 + 死掉了的边(貌似lyd第三版书上还是说的不可行边)先跑最大流. 在跑完以后的残余网络上,对于一条当前匹配的边 \( ...
- Noip模拟58 2021.9.21(中秋祭&&换机房祭)
第一次在学校过中秋节,给家里人视频电话,感觉快回家了很开心, 然后还吃了汉堡喝饮料非常爽,颓废了一会儿还换了新机房,$Linux2.0$非常dei,少爷机也非常快, 发现好像测评机又成了老爷机,这就是 ...
- 总结-一本通提高篇&算竞进阶记录
当一个人看见星空,就再无法忍受黑暗 为了点亮渐渐沉寂的星空 不想就这样退役 一定不会鸽の坑 . 一本通提高篇 . 算竞进阶 . CDQ & 整体二分 . 平衡树 . LCT . 字符串 . 随 ...
- 0x6A 网络流初步
CH Round #17-C 这个算是一个技能点吧,不点不会,点了就没什么了.懒得写看书吧书上的1应该是0... 我又回来了太懒了不想翻书还是写写吧 必须边的判定条件:该边流量为0且两端的点在残余网络 ...
- [考试反思]1019csp-s模拟测试80(a):天遣
A组题,所以把榜粘全了. 第6名,被卡在刚好正中间. 我最近干什么伤天害理的事了?(例如说没有在skyh去上厕所的时候捶他) 上来看T1,非常贴心出题人直接把递推式子给你了,然后就和斐波数的递推一样了 ...
- 二分图&网络流初步
链接 : 最小割&网络流应用 EK太低级了,不用. 那么请看:#6068. 「2017 山东一轮集训 Day4」棋盘,不用EK你试试? dinic模板及部分变形应用见zzz大佬的博客:网络流学 ...
随机推荐
- for循环小练习
for循环是前测试循环语句 for(初始值:判定条件:步长){ 循环语句 } For循环原理: For循环第一次执行:首先执行语句1,然后执行语句2,如果条件为真,向内执行执行循环语句3. 如果条件为 ...
- Hadoop(17)-MapReduce框架原理-MapReduce流程,Shuffle机制,Partition分区
MapReduce工作流程 1.准备待处理文件 2.job提交前生成一个处理规划 3.将切片信息job.split,配置信息job.xml和我们自己写的jar包交给yarn 4.yarn根据切片规划计 ...
- ruby 数据类型Range
范围(Range)无处不在:a 到 z. 0 到 9.等等.Ruby 支持范围,并允许我们以不同的方式使用范围: 作为序列的范围 作为条件的范围 作为间隔的范围 作为序列的范围 (1..5) #==& ...
- SSH远程登录和端口转发详解
SSH远程登录和端口转发详解 介绍 SSH 是创建在应用层和传输层基础上的安全协议,为计算机上的 Shell(壳层)提供安全的传输和使用环境. SSH 只是协议,有多种实现方式,本文基于其开源实 ...
- 一个新晋IT行业的努力Duiker
亲爱的朋友,你好! 我很开心能以这么一篇博客来开始我的IT努力之路.我叫Duiker,是一名软件工程专业的学生,想通过写博客来提升自己,充实自我. 首先,我要确立自己的学习编程目标: 1.将算 ...
- kafka topic 完全删除
kafka topic 完全删除 1.自动删除脚本(得配置server.properties 中 delete.topic.enable=true) ./kafka-topics.sh --zoo ...
- html页面导出word文档
1.加入两个外部js 1)FileSaver.js /* FileSaver.js * A saveAs() FileSaver implementation. * 1.3.2 * 2016-06-1 ...
- django序列化时间
具体代码: import json,time,datetime lis ={'time':datetime.date.today(),"username":"zhilei ...
- FPGA数字鉴相鉴频器的开发记录
1. 对于电机的锁相控制,需要对相差进行PI性质的环路滤波,但现有的锁相环中鉴频鉴相器输出为相差脉冲而非数字量,难以直接进行PI特性的环路滤波. 通过对晶振的非整数分频获取准确的参考时钟,基于触发器机 ...
- guacamole实现上传下载
目录 1. 源码解读 2. 上传下载的核心代码 分析的入手点,查看websocket连接的frame 看到首先服务端向客户端发送了filesystem请求,紧接着浏览器向服务端发送了get请求,并且后 ...