2019 ICPC 陕西西安邀请赛 D. Miku and Generals
传送门:https://nanti.jisuanke.com/t/39271
题意:
给你n个人,每个人有一个权值 a_i ,(a_i是可以被100整除的))现在需要你将n个人分成两组,有m个关系,a和b有关系代表a和b不能放在同一个组内,为了两组实力尽量平均,要你求两组权值差值最小时最大的值是哪一个
题解:
二分图染色+dp
首先我们知道n个人必须全选分为两组,其次题目保证有解
因此我们很容易想到如果a->b,b->c,那么a一定和c要分在同一组内
这样我们就得到了很多个联通块
错误想法:我们得到了num个联通块后直接将num个联通块做01背包就可以求出差值最小时最大值,dp状态定义为前i个物品,容量为j时的最大值,但是实际上这样有可能把错误的情况考虑进来,例如两个矛盾的块同时放进一个背包,例如这组数据
2
4 1
300 300 100 500
1 2
6 4
1000 2000 1000 1500 1000 1500
1 2
2 3
4 5
5 6
01背包得到的答案是600 和 4000,实际上应该是 800和5000
正确想法,我们将物品分成联通块后,对分成的两个联通块做差值,之后枚举差值能否达到才是最优解,为了防止差值为负,我们在中间加上一个比较大的数即可
代码:
错误写法:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef long long ll;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
struct EDGE {
int v, nxt;
} edge[maxn << 1];
int head[maxn], tot;
void add_edge(int u, int v) {
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
int a[maxn];
int num[maxn];
int num1, num2;
int vis[maxn];
int dp[205][maxn];
void dfs(int u, int flag) {
vis[u] = 1;
if(flag) num1 += a[u];
else num2 += a[u];
for(int i = head[u]; i != -1; i = edge[i].nxt) {
int v = edge[i].v;
if(vis[v]) continue;
dfs(v, !flag);
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int T;
scanf("%d", &T);
while(T--) {
int n, m;
memset(head, -1, sizeof(head));
tot = 0;
int cur = 0;
int sum = 0, ret;
memset(vis, 0, sizeof(vis));
memset(num, 0, sizeof(num));
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
a[i] /= 100;
sum += a[i];
}
ret = sum / 2;
for(int i = 1, u, v; i <= m; i++) {
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
num1 = 0, num2 = 0;
dfs(i, 0);
if(num1 != 0) {
num[++cur] = num1;
}
if(num2 != 0) {
num[++cur] = num2;
}
}
}
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= cur; i++) {
for(int j = 0; j <= ret; j++) {
dp[i][j] = dp[i - 1][j];
if(j >= num[i])dp[i][j] = max(dp[i][j], dp[i - 1][j - num[i]] + num[i]);
}
}
printf("%d\n", (sum - dp[cur][ret]) * 100);
}
return 0;
}
正确写法:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef long long ll;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
struct EDGE {
int v, nxt;
} edge[maxn << 1];
int head[maxn], tot;
void add_edge(int u, int v) {
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
int a[maxn];
int num[maxn];
int num1, num2;
int vis[maxn];
int dp[205][maxn];
void dfs(int u, int flag) {
vis[u] = 1;
if(flag) num1 += a[u];
else num2 += a[u];
for(int i = head[u]; i != -1; i = edge[i].nxt) {
int v = edge[i].v;
if(vis[v]) continue;
dfs(v, !flag);
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int T;
scanf("%d", &T);
while(T--) {
int n, m;
memset(head, -1, sizeof(head));
tot = 0;
int cur = 0;
int sum = 0, ret;
memset(vis, 0, sizeof(vis));
memset(num, 0, sizeof(num));
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
a[i] /= 100;
sum += a[i];
}
for(int i = 1, u, v; i <= m; i++) {
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
ret = 0;
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
num1 = 0, num2 = 0;
dfs(i, 0);
num[++cur] += abs (num1 - num2);
ret += abs(num1 - num2);
}
}
memset(dp, 0, sizeof(dp));
dp[0][100000] = 1;
for (int i = 1; i <= cur; i++) {
for (int j = -ret; j <= ret; j++) {
if (dp[i - 1][j - num[i] + 100000]) dp[i][j + 100000] = 1;
if (dp[i - 1][j + num[i] + 100000]) dp[i][j + 100000] = 1;
}
}
for (int i = 100000; i <= 100000 + ret; i++) {
if (dp[cur][i]) {
int x = i - 100000;
printf("%d\n", 100 * ((sum - x) / 2 + x));
break;
}
}
}
return 0;
}
2019 ICPC 陕西西安邀请赛 D. Miku and Generals的更多相关文章
- ACM-ICPC 2019 西安邀请赛 D.Miku and Generals(二分图+可行性背包)
“Miku is matchless in the world!” As everyone knows, Nakano Miku is interested in Japanese generals, ...
- 2019 ACM/ICPC Asia Regional shanxia D Miku and Generals (二分图黑白染色+01背包)
Miku is matchless in the world!” As everyone knows, Nakano Miku is interested in Japanese generals, ...
- 2019 icpc南昌全国邀请赛-网络选拔赛J题 树链剖分+离线询问
链接:https://nanti.jisuanke.com/t/38229 题意: 给一棵树,多次查询,每次查询两点之间权值<=k的边个数 题解: 离线询问,树链剖分后bit维护有贡献的位置即可 ...
- 计蒜客 39272.Tree-树链剖分(点权)+带修改区间异或和 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest E.) 2019ICPC西安邀请赛现场赛重现赛
Tree Ming and Hong are playing a simple game called nim game. They have nn piles of stones numbered ...
- ACM-ICPC 2018全国邀请赛(陕西西安)
一.火车晚点 星期五下午4.36的火车,我们3点到了长沙火车站.差不多4点了,提示,晚点1h45min,DZC马上说,不知道会不会延误郑州到西安的那趟车.过了一会,又提示,晚点2h17min,再过一会 ...
- 2014嘉杰信息杯ACM/ICPC湖南程序设计邀请赛暨第六届湘潭市程序设计竞赛
比赛链接: http://202.197.224.59/OnlineJudge2/index.php/Contest/problems/contest_id/36 题目来源: 2014嘉杰信息杯ACM ...
- 2019 ICPC 南昌网络赛
2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 ...
- 2019 ICPC Asia Nanjing Regional
2019 ICPC Asia Nanjing Regional A - Hard Problem 计蒜客 - 42395 若 n = 10,可以先取:6,7,8,9,10.然后随便从1,2,3,4,5 ...
- 西安区域赛 D.Miku and Generals 二分图+背包
Miku and Generals Describe "Miku is matchless in the world!" As everyone knows, Nakano Mik ...
随机推荐
- Qt qmake报错(TypeError: Property 'asciify' of object Core::Internal::UtilsJsExtension)
问题如题. 解决方案: 第一种 用下管理员权限来打开qt creator,再创建工程.有可能是没权限创建出源码工程目录 第二种 打开qt左边的项目上,可以看到这个项目的编译路径,修改成绝对路径,或者设 ...
- tyvj1467 通向聚会的道路
背景 Candy住在一个被划分为n个区域的神奇小镇中,其中Candy的家在编号为n的区域,Candy生日这天,大家都急急忙忙赶去Candy家庆祝Candy的生日. 描述 Candy共有t个朋友 ...
- python的str,unicode对象的encode和decode方法, Python中字符编码的总结和对比bytes和str
python_2.x_unicode_to_str.py a = u"中文字符"; a.encode("GBK"); #打印: '\xd6\xd0\xce\xc ...
- sum(),max(),avg(),RATIO_TO_REPORT()--分组统计
select id,area, sum(1) over() as 总记录数, sum(1) over(partition by id) as 分组记录数, sum(score) over() as 总 ...
- laravel 中使用tinker 验证驱动加载是否成功
在验证laravel 中 InvalidArgumentException Driver [WeiBo] not supported. public function weibo() { retu ...
- idea使用积累
1.初试化配置参照http://m.blog.csdn.net/robertohuang/article/details/75042116,很详细. 2.idea中忽略.idea,.iml这两个文件 ...
- @codeforces - 1106F@ Lunar New Year and a Recursive Sequence
目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义递推数列 f: (1)f[1] = f[2] = ... f ...
- ListView 适配器实现getviewtypecount() 数组越界IndexOutOfBoundException
ListView中Item的多布局显示,需要用到了getviewtypecount和getItemViewType这两个重写方法,但是做完后出现了如下提示错误: java.lang.ArrayInde ...
- Top 10 open source projects of 2015
Top 10 open source projects of 2015 Posted 15 Dec 2015Jen Wike Huger (Red Hat)Feed 188 up 31 comment ...
- Android Studio(十二):打包多个发布渠道的apk文件
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...