看别人写的才学会的。。。

我们考虑刚开始的一个点, 然后我们枚举接上去的一条一条链,

dp[mask]表示当前已经加进去点的状态是mask所需的最少边数。

反正就是很麻烦的一道题, 让我自己写我是写不出来的。。。 我好菜啊。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()using namespace std;const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e6 + 3;
const int p = 1e6 + 3;
const double eps = 1e-8;
const double PI = acos(-1);template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}int n, m;
int G[14][14];
int vtomask[14][1 << 14];
int dp[1 << 14], pre[1 << 14][3];
vector<int> road[1 << 14][14][14];
vector<PII> ans;int main() {memset(dp, inf, sizeof(dp));scanf("%d%d", &n, &m);for(int i = 0; i < m; i++) {int u, v; scanf("%d%d", &u, &v);u--; v--;G[u][v] = G[v][u] = 1;}for(int i = 0; i < n; i++) {for(int mask = 0; mask < (1 << n); mask++) {for(int j = 0; j < n; j++) {if(mask >> j & 1) {if(G[i][j]) vtomask[i][mask]++;}}}}for(int i = 0; i < n; i++) road[1 << i][i][i].push_back(i);for(int mask = 0; mask < (1 << n); mask++) {for(int u = 0; u < n; u++) {for(int v = 0; v < n; v++) {if(!SZ(road[mask][u][v])) continue;for(int z = 0; z < n; z++) {if(mask >> z & 1) continue;if(!G[v][z]) continue;int nxtmask = mask | (1 << z);if(SZ(road[nxtmask][u][z])) continue;road[nxtmask][u][z] = road[mask][u][v];road[nxtmask][u][z].push_back(z);}}}}dp[1] = 0;for(int mask = 1; mask < (1 << n); mask++) {if(dp[mask] >= inf) continue;for(int u = 0; u < n; u++) {if(mask >> u & 1) continue;if(!vtomask[u][mask]) continue;if(vtomask[u][mask] >= 2) {int nxtmask = mask | (1 << u);if(chkmin(dp[nxtmask], dp[mask] + 2)) {pre[nxtmask][0] = mask;pre[nxtmask][1] = u;pre[nxtmask][2] = -1;}}for(int v = u + 1; v < n; v++) {if(mask >> v & 1) continue;if(!vtomask[v][mask]) continue;int amask = ((1 << n) - 1) ^ mask ^ (1 << u) ^ (1 << v);for(int smask = amask; ; smask = (smask - 1) & amask) {int tmask = smask | (1 << u) | (1 << v);if(SZ(road[tmask][u][v])) {if(chkmin(dp[mask | tmask], dp[mask] + SZ(road[tmask][u][v]) + 1)) {pre[mask | tmask][0] = mask;pre[mask | tmask][1] = u;pre[mask | tmask][2] = v;}}if(!smask) break;}}}}printf("%d\n", dp[(1 << n) - 1]);int mask = (1 << n) - 1;while(mask != 1) {int pmask = pre[mask][0];int u = pre[mask][1];int v = pre[mask][2];if(~v) {int tmask = mask ^ pmask;for(int i = 1; i < SZ(road[tmask][u][v]); i++)ans.push_back(mk(road[tmask][u][v][i - 1], road[tmask][u][v][i]));for(int i = 0; i < n; i++) {if((pmask >> i & 1) && G[u][i]) {ans.push_back(mk(i, u));break;}}for(int i = 0; i < n; i++) {if((pmask >> i & 1) && G[v][i]) {ans.push_back(mk(i, v));break;}}} else {for(int i = 0, c = 2; c; i++) {if(G[u][i] && (pmask >> i & 1)) {ans.push_back(mk(u, i));c--;}}}mask = pmask;}for(auto& t : ans) printf("%d %d\n", t.fi + 1, t.se + 1);return 0;
}/*
*/

转载于:https://www.cnblogs.com/CJLHY/p/10760136.html

Codeforces 1155F Delivery Oligopoly dp(看题解)相关推荐

  1. Codeforces Round 63 (Rated for Div. 2) F. Delivery Oligopoly dp+图论状态转移

    题目链接: https://codeforces.com/contest/1155/problem/F 题意: 现在给你一个 141414 个点的无向边双联通图,现在要你删掉一些边,使得留下来的边最少 ...

  2. Codeforces 596D Wilbur and Trees dp (看题解)

    一直在考虑, 每一段的贡献, 没想到这个东西能直接dp..因为所有的h都是一样的. #include<bits/stdc++.h> #define LL long long #define ...

  3. Codeforces Round #702 (Div. 3)A-G题解

    Codeforces Round #702 (Div. 3)A-G题解 比赛链接:https://codeforces.ml/contest/1490 这场F读错题意白给一发,G二分的if(dp[mi ...

  4. Codeforces Round #674 (Div. 3)A-F题解

    Codeforces Round #674 (Div. 3)A-F题解 比赛链接:https://codeforces.com/contest/1426 A题 水题不写题解 #include<b ...

  5. Codeforces 919D Substring (拓扑图DP)

    Codeforces 919D Substring (拓扑图DP) 手动博客搬家: 本文发表于20180716 10:53:12, 原地址https://blog.csdn.net/suncongbo ...

  6. ZOJ 3962 Seven Segment Display(数位DP)题解

    题意:给一个16进制8位数,给定每个数字的贡献,问你贡献和. 思路:数位DP,想了很久用什么表示状态,看题解说用和就行,其他的都算是比较正常的数位DP. 代码: #include<iostrea ...

  7. CodeForces 711C - Coloring Trees DP

    /*http://codeforces.com/problemset/problem/711/C http://codeforces.com/blog/entry/46830官方题解:We compu ...

  8. Codeforces Round #686 (Div. 3) A-F题解

    Codeforces Round #686 (Div. 3) A-F题解 A. Special Permutation 题意 给定 nnn ,输出一个长度为 nnn 的全排列,每个位置 iii 上的数 ...

  9. Codeforces Round #693 (Div. 3)部分题解

    Codeforces Round #693 (Div. 3) 部分题解 D. Even-Odd Game 思路: 贪心:田忌赛马 (1)先将数组从大到小排序,取数时从大到小取,用一个ans变量记录取数 ...

最新文章

  1. 腾讯张正友:计算机视觉的三生三世
  2. 把SAP Cloud for Customer嵌入到IFrame里
  3. mysql 1005 - can't create table_关于创建数据表报错一例(ERROR 1005 Can’t create table (errno: 121))...
  4. 你如何摆平秋季问题皮肤
  5. cs架构用什么语言开发_我为什么建议Python开发者将ES6作为第二语言
  6. c语言应用报告,C语言:数组的应用实验报告.doc
  7. mysql索引0affected_mysql 创建索引和删除索引
  8. Word01-从正文处开始插入页码
  9. 金店管理系统的几个经验和教训
  10. paip..提升安全性----增加自毁功能
  11. Spring源码阅读之在spring源码中创建一个gradle测试模块
  12. 常见气象数据获取方式及批量下载代码汇总
  13. POI读取PPT图表模板,动态改变图表数据,操作图表
  14. html字数统计,html中利用javascript实现文本框字数的动态计算
  15. 旅游行业的手机App Top5
  16. 病毒木马入侵招数专题
  17. 计算机二级第一次考试不及格有没有影响,计算机二级还没有过吗?
  18. Google Dremel 原理 – 如何能 3 秒分析 1PB
  19. android德地图点聚合,点聚合-点标记-示例中心-JS API 示例 | 高德地图API
  20. duet连win10,duetdisplay这个软件在win10上用不了?安装vs2015的时候想取消安装没有点取消...

热门文章

  1. 2022年机修钳工(中级)考试题库及模拟考试
  2. matlab emd功率谱密度,基于EMD方法的地心运动时间序列分析
  3. python mysql where in 对列表(list,,array)问题
  4. MindManager2022激活码序列号密钥怎么注册教程下载介绍教程
  5. 小学生python游戏编程arcade----可旋转的坦克的发射子弹
  6. 计算机无法完成评估,Windows Vista下系统评分无法完成的问题
  7. java实现一个语法检查器_Java语法检查
  8. js 中实现百分比计算
  9. [iOS]分享文件到QQ好友或微信好友
  10. ​汽车域控制器架构和OTA的心脏:网关的四大豪门(下)