2013 Multi-University Training Contest 9
HDU-4687 Boke and Tsukkomi
题意:给定一个简单图,询问哪些边如果选择的话会使得最大的连边数减少。
解法:套用一般图的最大匹配算法(带花树)先算出最大匹配数,然后枚举一条边被选择(注意:如果改变被选择,则两端点相邻的边都应删除),看是否只减少一条匹配边。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std; const int MAXN = ;
int n, m;
int u[], v[]; struct Graph { bool mat[MAXN + ][MAXN + ];
int n; bool inque[MAXN + ];
int que[MAXN], head, tail; int match[MAXN + ], father[MAXN + ], base[MAXN + ]; int inpath[MAXN + ];
static int pcnt; // count of paths have existed int inblossom[MAXN + ];
static int bcnt; // count of blossoms have existed void init(int _n) {
n = _n;
for (int i = ; i <= n; ++i) {
match[i] = ;
for (int j = ; j <= n; ++j)
mat[i][j] = false;
}
} int pop() { return que[head++]; } void push(int x) {
que[tail++] = x;
inque[x] = true;
} void add_edge(int a, int b) {
mat[a][b] = mat[b][a] = true;
} int find_ancestor(int u, int v) {
++pcnt;
while (u) {
u = base[u];
inpath[u] = pcnt;
u = father[match[u]];
// if match[u] == 0, meaning u is the root node, it also works, because father[0] == 0
}
while (true) {
v = base[v];
if (inpath[v] == pcnt) return v;
v = father[match[v]];
}
} void reset(int u, int anc) {
while (u != anc) {
int v = match[u];
inblossom[base[v]] = bcnt;
inblossom[base[u]] = bcnt;
v = father[v];
if (base[v] != anc) father[v] = match[u];
u = v;
}
} void contract(int u, int v) {
int anc = find_ancestor(u, v);
++bcnt;
reset(u, anc);
reset(v, anc);
if (base[u] != anc) father[u] = v;
if (base[v] != anc) father[v] = u;
for (int i = ; i <= n; ++i)
if (inblossom[base[i]] == bcnt) {
base[i] = anc;
if (!inque[i]) push(i);
}
} int find_augment(int start) {
for (int i = ; i <= n; ++i) {
father[i] = ;
inque[i] = false;
base[i] = i;
}
head = ; tail = ; push(start);
while (head < tail) {
int u = pop();
for (int v = ; v <= n; ++v)
if (mat[u][v] && base[v] != base[u] && match[v] != u) {
if (v == start || (match[v] && father[match[v]]))
// node v is out-point
contract(u, v); // make blossom
else {
if (father[v] == ) { // not in-point
if (match[v]) { // has matched
push(match[v]); // match[v] becomes out-point
father[v] = u; // v becomes in-point
} else {
father[v] = u; // node v is another end
return v;
}
}
}
}
}
return ;
} void augment(int finish) {
int u = finish, v, w;
while (u) {
v = father[u];
w = match[v];
match[u] = v;
match[v] = u;
u = w;
}
} int graph_max_match() {
int ans = ;
for (int i = ; i <= n; ++i)
if (match[i] == ) {
int finish = find_augment(i);
if (finish) {
augment(finish);
ans += ;
}
}
return ans;
} } g; int Graph::bcnt = , Graph::pcnt = ;
vector<int>vt; int main() {
while (scanf("%d %d", &n, &m) != EOF) {
g.init(n);
vt.clear();
bool first = true;
for (int i = ; i < m; ++i) {
scanf("%d %d", &u[i], &v[i]);
g.add_edge(u[i], v[i]);
}
int MaxPair = g.graph_max_match() / ; // 返回的是匹配的点数
for (int i = ; i < m; ++i) {
g.init(n);
int a = u[i], b = v[i];
for (int j = ; j < m; ++j) { // 如果匹配这条边那么两个端点其他连边都是不能匹配的
if (u[j] == a || u[j] == b || v[j] == a || v[j] == b) continue;
g.add_edge(u[j], v[j]);
}
int tmp = g.graph_max_match() / ;
if (tmp != MaxPair - ) vt.push_back(i+);
}
printf("%d\n", vt.size());
for (int i = ; i < (int)vt.size(); ++i) {
printf(i == ? "%d" : " %d", vt[i]);
}
puts("");
}
return ;
}
2013 Multi-University Training Contest 9的更多相关文章
- Integer Partition(hdu4658)2013 Multi-University Training Contest 6 整数拆分二
Integer Partition Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- Partition(hdu4651)2013 Multi-University Training Contest 5
Partition Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków
ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik’s Rect ...
- Partition(hdu4651)2013 Multi-University Training Contest 5----(整数拆分一)
Partition Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- JSU 2013 Summer Individual Ranking Contest - 5
JSU 2013 Summer Individual Ranking Contest - 5 密码:本套题选题权归JSU所有,需要密码请联系(http://blog.csdn.net/yew1eb). ...
- HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/500 ...
- 2015 Multi-University Training Contest 8 hdu 5390 tree
tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...
- hdu 4946 2014 Multi-University Training Contest 8
Area of Mushroom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 2016 Multi-University Training Contest 2 D. Differencia
Differencia Time Limit: 10000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
随机推荐
- Linux异步IO【转】
转自:http://blog.chinaunix.net/uid-24567872-id-87676.html Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出 ...
- Linux批量修改用户密码
对系统定期修改密码是一个很重要的安全常识,通常,我们修改用户密码都使用passwd user这样的命名来修改密码,但是这样会进入交互模式,即使使用脚本也不能很方便的批量修改,除非使用expect这样的 ...
- JavaEE基础(十三)
1.常见对象(StringBuffer类的概述) A:StringBuffer类概述 通过JDK提供的API,查看StringBuffer类的说明 线程安全的可变字符序列 B:StringBuffer ...
- mysql之使用xtrabackup进行物理备份、恢复、在线克隆从库、在线重做主从
注:图片来自<深入浅出MySQL 数据库开发 优化与管理维护 第2版> 物理备份和恢复 1.冷备份:停掉mysql再备份,一般很少用,因为很多应用不允许长时间停机,停机备份的可以直接CP数 ...
- c# 遍历子控件,比如Form下的group,或者panel
方法很好用.目的是遍历所有容器的子控件... 方法1private void GetControl(Control.ControlCollection ctc, ref int checkNull) ...
- 最全面的Java多线程用法解析
1.创建线程 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口.在使用Runnable接口时需要建立一个Thread实例.因此,无论是通过Thread类还是Runnable ...
- Buy Tickets
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 16010 Accepted: 7983 Descript ...
- Unity物理投射相关问题整理
1.投射目标是否需要附加刚体,是否可忽略触发器? 默认既支持触发器,也支持刚体.投射的最后一个参数queryTriggerInteraction可以设置,是否包含触发器事件. 2.非射线投射,是否有接 ...
- Scrapy集成selenium+PhantomJS+代理IP 解析js动态内容
转载于:http://blog.aizhet.com/web/16523.html
- 2016年11月22日 星期二 --出埃及记 Exodus 20:13
2016年11月22日 星期二 --出埃及记 Exodus 20:13 "You shall not murder.不可杀人.