这题写起来真的有点麻烦,按照官方题解的写法

先建图,然后求强连通分量,然后判断掉不符合条件的换

最后做dp转移即可

虽然看起来复杂度很高,但是n只有15,所以问题不大

  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <set>
  5. #include <map>
  6. #include <bitset>
  7. #include <algorithm>
  8. #include <iomanip>
  9. #include <cmath>
  10. #include <ctime>
  11. #include <functional>
  12. #include <unordered_set>
  13. #include <unordered_map>
  14. #include <queue>
  15. #include <deque>
  16. #include <stack>
  17. #include <complex>
  18. #include <cassert>
  19. #include <random>
  20. #include <cstring>
  21. #include <numeric>
  22. #define ll long long
  23. #define ld long double
  24. #define null NULL
  25. #define all(a) a.begin(), a.end()
  26. #define forn(i, n) for (int i = 0; i < n; ++i)
  27. #define sz(a) (int)a.size()
  28. #define lson l , m , rt << 1
  29. #define rson m + 1 , r , rt << 1 | 1
  30. #define bitCount(a) __builtin_popcount(a)
  31. template<class T> int gmax(T &a, T b) { if (b > a) { a = b; return 1; } return 0; }
  32. template<class T> int gmin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; }
  33. using namespace std;
  34. string to_string(string s) { return '"' + s + '"'; }
  35. string to_string(const char* s) { return to_string((string) s); }
  36. string to_string(bool b) { return (b ? "true" : "false"); }
  37. template <typename A, typename B>
  38. string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }
  39. template <typename A>
  40. string to_string(A v) { bool first = true; string res = "{"; for (const auto &x : v) { if (!first) { res += ", "; } first = false; res += to_string(x); } res += "}"; return res; }
  41. void debug_out() { cerr << endl; }
  42. template <typename Head, typename... Tail>
  43. void debug_out(Head H, Tail... T) { cerr << " " << to_string(H); debug_out(T...); }
  44. #ifdef LOCAL
  45. #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
  46. #else
  47. #define debug(...) 42
  48. #endif
  49. const int MAXN = 75005;
  50. vector<int> graph[MAXN];
  51. vector<int> group[MAXN];
  52. int dfn[MAXN], low[MAXN];
  53. int dcnt;
  54. int col[MAXN + 5], ccnt;
  55. bool vis[MAXN + 5];
  56. int stk[MAXN + 5], tp;
  57. vector<pair<int, int>> dp[32768];
  58. void Tarjan_scc(int u) {
  59. dfn[u] = ++dcnt, low[u] = dcnt, vis[u] = true;
  60. stk[++tp] = u;
  61. for(int i = 0; i < (int)graph[u].size(); i++) {
  62. int v = graph[u][i];
  63. if(!dfn[v]) {
  64. Tarjan_scc(v);
  65. low[u] = min(low[u], low[v]);
  66. } else if(vis[v]) low[u] = min(low[u], low[v]);
  67. }
  68. if(dfn[u] == low[u]) {
  69. ++ccnt;
  70. while(true) {
  71. col[stk[tp]] = ccnt;
  72. vis[stk[tp]] = false;
  73. if(stk[tp--] == u)
  74. break;
  75. }
  76. }
  77. }
  78. int main() {
  79. int k;
  80. while(~scanf("%d", &k)) {
  81. tp = -1; ccnt = 0; dcnt = 0;
  82. for(int i = 0; i < MAXN; ++i) {
  83. dfn[i] = 0;
  84. graph[i].clear();
  85. group[i].clear();
  86. }
  87. vector<ll> sum;
  88. vector<pair<int, int> > vc;
  89. map<ll, pair<int, int> > mp;
  90. int tot = 0;
  91. ll allSum = 0;
  92. for(int i = 0; i < k; ++i) {
  93. int x; scanf("%d", &x);
  94. ll tmpSum = 0;
  95. for(int j = 0; j < x; ++j) {
  96. int y; scanf("%d", &y);
  97. vc.push_back(make_pair(y, i));
  98. mp[y] = make_pair(tot, i);
  99. tot ++;
  100. tmpSum += y;
  101. }
  102. sum.push_back(tmpSum);
  103. allSum += tmpSum;
  104. }
  105. // debug(allSum);
  106. if(allSum % k) {
  107. printf("No\n");
  108. continue;
  109. }
  110. allSum /= k;
  111. set<int> selfCircle;
  112. set<pair<int, int>> hasEdge;
  113. // debug(allSum);
  114. for(int i = 0, len = vc.size(); i < len; ++i) {
  115. ll searchNum = allSum - sum[vc[i].second] + vc[i].first;
  116. if(mp.find(searchNum) == mp.end()) continue;
  117. else if( mp[searchNum].second == vc[i].second && mp[searchNum].first != i) {
  118. // solve specfial condition
  119. continue;
  120. } else if(mp[searchNum].first == i) {
  121. // debug(i);
  122. selfCircle.insert(i);
  123. }
  124. graph[i].push_back(mp[searchNum].first);
  125. hasEdge.insert(make_pair(i, mp[searchNum].first));
  126. debug(i, mp[searchNum].first);
  127. }
  128. for(int i = 0; i < tot; ++i) {
  129. if(!dfn[i]) Tarjan_scc(i);
  130. }
  131. for(int i = 0; i < tot; ++i) {
  132. // printf("%d ", col[i]);
  133. group[col[i]].push_back(i);
  134. }
  135. // printf("\n");
  136. for(int i = 1; i <= ccnt; ++i) {
  137. // debug(i, group[i].size());
  138. if(group[i].size() == 1 && selfCircle.count(group[i][0])) {
  139. int id = group[i][0];
  140. vector<pair<int, int> > tmpPair;
  141. tmpPair.push_back(make_pair(vc[id].first, vc[id].second + 1));
  142. dp[1<<vc[id].second] = tmpPair;
  143. // debug(dp[1<<vc[id].second]);
  144. }
  145. else if(group[i].size() > 1) {
  146. vector<pair<int, int> > tmpPair;
  147. int tmp = 0;
  148. int len = group[i].size();
  149. bool suc = true;
  150. for(int j = 0; j < len; ++j) {
  151. int to = group[i][j];
  152. if(tmp & (1<<vc[to].second)) { suc = false; break; }
  153. tmp |= 1<<vc[to].second;
  154. }
  155. if(suc == false) {
  156. continue;
  157. }
  158. for(int j = 0; j < len; ++j) {
  159. for(int k = 0; k < len; ++k) {
  160. int fr = group[i][j]; int to = group[i][k];
  161. if(hasEdge.count(make_pair(fr, to))) {
  162. tmpPair.push_back(make_pair(vc[to].first, vc[fr].second + 1));
  163. }
  164. }
  165. }
  166. dp[tmp] = tmpPair;
  167. // debug(dp[tmp], tmp);
  168. }
  169. }
  170. for(int i = 0; i < (1<<k); ++i) {
  171. for (int s=(i-1)&i; s; s=(s-1)&i) {
  172. int t = i ^ s;
  173. if(dp[s].size() > 0 && dp[t].size() > 0) {
  174. dp[i] = dp[s];
  175. dp[i].insert(dp[i].end(), dp[t].begin(), dp[t].end());
  176. break;
  177. }
  178. }
  179. }
  180. auto cmp = [&](pair<int, int> &A, pair<int, int> &B) {
  181. return mp[A.first].second < mp[B.first].second;
  182. };
  183. int end = (1<<k) - 1;
  184. if(dp[end].size() > 0 ) {
  185. printf("Yes\n");
  186. // debug(dp[end]);
  187. sort(dp[end].begin(), dp[end].end(), cmp);
  188. for(int i = 0; i < k; ++i) {
  189. printf("%d %d\n", dp[end][i].first, dp[end][i].second);
  190. }
  191. } else printf("No\n");
  192. }
  193. return 0;
  194. }

Codeforces Round #599 (Div. 2) E. Sum Balance的更多相关文章

  1. Codeforces Round #599 (Div. 1) C. Sum Balance 图论 dp

    C. Sum Balance Ujan has a lot of numbers in his boxes. He likes order and balance, so he decided to ...

  2. Codeforces Round #599 (Div. 2) D. 0-1 MST(bfs+set)

    Codeforces Round #599 (Div. 2) D. 0-1 MST Description Ujan has a lot of useless stuff in his drawers ...

  3. Codeforces Round #530 (Div. 2):D. Sum in the tree (题解)

    D. Sum in the tree 题目链接:https://codeforces.com/contest/1099/problem/D 题意: 给出一棵树,以及每个点的si,这里的si代表从i号结 ...

  4. Codeforces Round #599 (Div. 2)

    久违的写篇博客吧 A. Maximum Square 题目链接:https://codeforces.com/contest/1243/problem/A 题意: 给定n个栅栏,对这n个栅栏进行任意排 ...

  5. Codeforces Round #599 (Div. 2) A,B1,B2,C 【待补 D】

    排序+暴力 #include<bits/stdc++.h> using namespace std; #define int long long #define N 1005000 int ...

  6. Codeforces Round #530 (Div. 2) D. Sum in the tree 树上贪心

    D. Sum in the tree 题意 给出一颗树,奇数层数的点有值,值代表从1到该点的简单路的权值的和,偶数层数的点权值被擦去了 问所有节点的和的最小可能是多少 思路 对于每一个-1(也就是值未 ...

  7. Codeforces Round #599 (Div. 2) B1. Character Swap (Easy Version)

    This problem is different from the hard version. In this version Ujan makes exactly one exchange. Yo ...

  8. Codeforces Round #599 (Div. 2)D 边很多的只有0和1的MST

    题:https://codeforces.com/contest/1243/problem/D 分析:找全部可以用边权为0的点连起来的全部块 然后这些块之间相连肯定得通过边权为1的边进行连接 所以答案 ...

  9. Codeforces Round #530 (Div. 1) 1098A Sum in the tree

    A. Sum in the tree Mitya has a rooted tree with nn vertices indexed from 11 to nn, where the root ha ...

随机推荐

  1. 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(1)

    .NET Core 3.0已经发布了,除了一大堆令人激动的功能以外,也增加了对WPF的正式支持, 那么WPF在.NET Core 3.0下的开发体验如何呢? 本文利用了Stylet框架开发.NET C ...

  2. 引入flask_cache时出现ModuleNotFoundError: No module named 'flask.ext'

    环境: centos 7.3 python 3.6 flask 1.0.2 flask-cache 0.13.1 引入flask_cache后运行时,出现以下错误 Traceback (most re ...

  3. RocketMQ事务消息学习及刨坑过程

    一.背景 MQ组件是系统架构里必不可少的一门利器,设计层面可以降低系统耦合度,高并发场景又可以起到削峰填谷的作用,从单体应用到集群部署方案,再到现在的微服务架构,MQ凭借其优秀的性能和高可靠性,得到了 ...

  4. Unreal Engine 4 系列教程 Part 1:入门

    原文:Unreal Engine 4 Tutorial for Beginners: Getting Started 作者:Tommy Tran 译者:Shuchang Liu 本篇教程将引导你安装U ...

  5. .net工作流引擎ccflow开发平台属性功能的隐藏显示介绍

    关键字: 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 表单引擎 工作流功能说明  工作流设计 工作流快速开发平台   业务流程管理   bpm工作流系统  java工 ...

  6. Web前端助手-功能丰富的Chrome插件

    整合优秀的前端实用工具.免费,可配置的强大工具集 示例 安装 github仓库: https://github.com/zxlie/FeHelper 官网地址:https://www.baidufe. ...

  7. powershell下ssh客户端套件实现

    有时会需要和Linux机器进行交互.所以这时就需要在Powershell中使用SSH. 0x01 查找Powershell中的SSH功能模块 如图,显示没有find-module的命令,需要安装Pac ...

  8. 微信小程序尺寸单位rpx以及样式相关介绍

    rpx单位是微信小程序中css的尺寸单位,rpx可以根据屏幕宽度进行自适应.规定屏幕宽为750rpx.如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375p ...

  9. python编程系列---Pycharm快捷键(更新中....)

    以下是我常用到的Pycharm快捷键(还有很多,只是我暂时用的最多的就这些): 在开发过程中,经常使用一些快捷键会大大提高开发效率,不要因为看这多而不用,常用的就那些,用得多就都记住了,脱离鼠标,逼格 ...

  10. .NET中国开发者峰会11.9 下午分会场1 内容解析

    China .NET Conf 2019中国 .NET 开发者峰会即将在上海召开,这次大会是一届完全由社区组织举办的中国.NET 开发者盛会,我们筹备大会之初就定下了大会的主题是“开源.共享.创新”. ...