CF1155F Delivery Oligopoly
题意:给定简单无向图,求一个最小的边集使得这些点是边双,输出方案。n <= 14
解:考虑一个边双肯定是一条一条的链拼起来的。于是每次枚举一条链加上去就行了。
设fs表示点集s形成边双的最小边数。linki,j,s表示点集s能否形成一个i - j的链。link2x,s表示点x和点集s是否直接相连。
上面这些数组都要记录方案,特别地,link2要记录两个方案,为了应对拼上去的链退化成一个点的情况。
- #include <bits/stdc++.h>
- const int N = ;
- struct Edge {
- int nex, v;
- }edge[N << ]; int tp;
- struct Node {
- int x, y, t;
- Node(int X = , int Y = , int T = ) {
- x = X;
- y = Y;
- t = T;
- }
- }fr3[N];
- int pw[N], cnt[N], f[N], e[N], n, m;
- bool link[][][N], link2[][N];
- int fr[][][N], fr2[][N], fr22[][N];
- inline void add(int x, int y) {
- tp++;
- edge[tp].v = y;
- edge[tp].nex = e[x];
- e[x] = tp;
- return;
- }
- void out(int x, int y, int s) {
- if(cnt[s] == ) return;
- printf("%d %d \n", y + , fr[x][y][s]);
- out(x, fr[x][y][s] - , s ^ ( << y));
- return;
- }
- void out3(int s) {
- if(cnt[s] == ) return;
- int x = fr3[s].x, y = fr3[s].y, t = fr3[s].t;
- out(x, y, t);
- printf("%d %d \n", x + , fr2[x][s ^ t]);
- if(x != y) printf("%d %d \n", y + , fr2[y][s ^ t]);
- else printf("%d %d \n", y + , fr22[y][s ^ t]);
- out3(s ^ t);
- return;
- }
- int main() {
- scanf("%d%d", &n, &m);
- for(int i = , x, y; i <= m; i++) {
- scanf("%d%d", &x, &y);
- add(x, y);
- add(y, x);
- }
- int lm = ( << n) - ; /// lm = 111111...1
- for(int i = ; i <= lm; i++) {
- cnt[i] = + cnt[i - (i & (-i))];
- if(i > ) pw[i] = pw[i >> ] + ;
- }
- for(int x = ; x < n; x++) {
- for(int s = ; s <= lm; s++) {
- /// link2[x][s]
- if((s >> x) & ) continue;
- for(int i = e[x + ]; i; i = edge[i].nex) {
- int y = edge[i].v - ;
- if((s >> y) & ) {
- link2[x][s] = ;
- if(!fr2[x][s]) {
- fr2[x][s] = y + ;
- }
- else {
- fr22[x][s] = y + ;
- break;
- }
- }
- }
- }
- }
- for(int i = ; i < n; i++) {
- link[i][i][ << i] = ;
- }
- for(int s = ; s < lm; s++) {
- for(int t1 = s, i; t1; t1 ^= ( << i)) {
- i = pw[t1 & (-t1)];
- /// i + 1
- for(int t2 = s, x; t2; t2 ^= ( << x)) {
- x = pw[t2 & (-t2)];
- /// f[i][x][s]
- if(!link[i][x][s]) continue;
- for(int j = e[x + ]; j; j = edge[j].nex) {
- int y = edge[j].v - ;
- if(((s >> y) & ) == ) {
- link[i][y][s | ( << y)] = ;
- fr[i][y][s | ( << y)] = x + ;
- }
- }
- }
- }
- }
- memset(f, 0x3f, sizeof(f));
- f[] = ;
- for(int s = ; s <= lm; s++) {
- /// f[s]
- for(int t = s & (s - ); t; t = (t - ) & s) {
- for(int t1 = t, x; t1; t1 ^= ( << x)) {
- x = pw[t1 & (-t1)];
- for(int t2 = t, y; t2; t2 ^= ( << y)) {
- y = pw[t2 & (-t2)];
- /// link[x][y][t] link2[x][s ^ t] link2[y][s ^ t]
- if(link[x][y][t] && link2[x][s ^ t] && link2[y][s ^ t] && (x != y || fr22[x][s ^ t])) {
- if(f[s] > f[s ^ t] + cnt[t] + ) {
- f[s] = f[s ^ t] + cnt[t] + ;
- fr3[s] = Node(x, y, t);
- }
- }
- }
- }
- }
- }
- printf("%d\n", f[lm]);
- out3(lm);
- return ;
- }
AC代码
CF1155F Delivery Oligopoly的更多相关文章
- Codeforces 1155F Delivery Oligopoly dp(看题解)
看别人写的才学会的... 我们考虑刚开始的一个点, 然后我们枚举接上去的一条一条链, dp[mask]表示当前已经加进去点的状态是mask所需的最少边数. 反正就是很麻烦的一道题, 让我自己写我是写不 ...
- 【Virt.Contest】CF1155(div.2)
CF 传送门 T1:Reverse a Substring 只有本身单调不减的字符串不能转换为字典序更小的字符串.否则肯定会出现 \(s_i>s_{i+1}\) 的情况. 所以只要从头到尾扫一遍 ...
- 《Continuous Delivery》 Notes 1: The problem of delivering software
What is "Deployment pipeline"? A deployment pipeline is an automated implementation of you ...
- zoj 3469 Food Delivery 区间dp + 提前计算费用
Time Limit: 2 Seconds Memory Limit: 65536 KB When we are focusing on solving problems, we usual ...
- 【IOS笔记】Event Delivery: The Responder Chain
Event Delivery: The Responder Chain 事件分发--响应链 When you design your app, it’s likely that you want t ...
- Content Delivery Network
Coding Standards & Best Practices 7 Reasons to use a Content Delivery Network CDN公共库汇总
- codeforces 653D D. Delivery Bears(二分+网络流)
题目链接: D. Delivery Bears time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- zoj 3742 Delivery 好题
Delivery 题目还是自己看吧 - -! 看似图论,实际上是一个考察思维以及数据结构的题. 我们对于先前和向后的边分别进行统计. 对询问离线. 小边按照左端点从大到小排序. 1.对于向后的边,询问 ...
- Repost: Set Delivery Block on SO
If SO is incomplete, then automatically set the delivery block on the SO header. as suggested by ear ...
随机推荐
- Poj1477
Box of Bricks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24101 Accepted: 9378 De ...
- 禁用事件event默认行为
在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性指定的页. js中return false作用一般是 ...
- App隐私条款
欢迎光临本app,请您仔细阅读以下条款,如果您对本协议的任何条款表示异议,您可以选择不使用本app:进入本app则意味着您将同意遵守本协议下全部规定,并完全服从于app开发者的统一管理. 第一章 总则 ...
- django 问题综合
orm部分 本篇文章我会持续更新,把开发中遇到的一切orm相关的问题都放在这里 mysql索引报错 使用django 的orm,数据库用的mysql,在使用makemigrations和migrate ...
- Linux/Ubuntu 16.04 安装编辑器 Sublime Text 3
在ubuntu 16.04 系统上使用Sublime Text 3 编辑文本还是不错的, 先到官网下载安装包,链接:http://www.sublimetext.com/3 ,下载对应的版本,64位或 ...
- LeetCode算法题-Largest Number At Least Twice of Others(Java实现)
这是悦乐书的第308次更新,第328篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第177题(顺位题号是747).在给定的整数数组中,总有一个最大的元素.查找数组中的最大 ...
- #032 有空就看PTA
我咋买书了? 上学期
- 【java学习】Intelli Idea集成开发工具的使用
== mac版直接下载地址: https://download.jetbrains.com/idea/ideaIU-2018.1.6.dmg ==mac配置java环境变量: https://ji ...
- 安装Linux虚拟系统
VMWare创建虚拟机与Linux系统的安装 准备工作:VMWare虚拟机,Linux系统镜像 创建好虚拟机之后就可以进入Bios(Basic input ouput system)界面设置安装引导顺 ...
- 蚂蚁 uva 10881
思路: 一,两个点相撞然后,相互弹开.这样其实和两个点穿过去差不多, 但是对于单个点而言,这样肯定不行. 二,当你发现了不管什么情况,这些点的相对位置是不变的, 比如 1, 4, 3, 2 不管怎么移 ...