传送门: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的更多相关文章

  1. ACM-ICPC 2019 西安邀请赛 D.Miku and Generals(二分图+可行性背包)

    “Miku is matchless in the world!” As everyone knows, Nakano Miku is interested in Japanese generals, ...

  2. 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, ...

  3. 2019 icpc南昌全国邀请赛-网络选拔赛J题 树链剖分+离线询问

    链接:https://nanti.jisuanke.com/t/38229 题意: 给一棵树,多次查询,每次查询两点之间权值<=k的边个数 题解: 离线询问,树链剖分后bit维护有贡献的位置即可 ...

  4. 计蒜客 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  ...

  5. ACM-ICPC 2018全国邀请赛(陕西西安)

    一.火车晚点 星期五下午4.36的火车,我们3点到了长沙火车站.差不多4点了,提示,晚点1h45min,DZC马上说,不知道会不会延误郑州到西安的那趟车.过了一会,又提示,晚点2h17min,再过一会 ...

  6. 2014嘉杰信息杯ACM/ICPC湖南程序设计邀请赛暨第六届湘潭市程序设计竞赛

    比赛链接: http://202.197.224.59/OnlineJudge2/index.php/Contest/problems/contest_id/36 题目来源: 2014嘉杰信息杯ACM ...

  7. 2019 ICPC 南昌网络赛

    2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 ...

  8. 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 ...

  9. 西安区域赛 D.Miku and Generals 二分图+背包

    Miku and Generals Describe "Miku is matchless in the world!" As everyone knows, Nakano Mik ...

随机推荐

  1. Qt qmake报错(TypeError: Property 'asciify' of object Core::Internal::UtilsJsExtension)

    问题如题. 解决方案: 第一种 用下管理员权限来打开qt creator,再创建工程.有可能是没权限创建出源码工程目录 第二种 打开qt左边的项目上,可以看到这个项目的编译路径,修改成绝对路径,或者设 ...

  2. tyvj1467 通向聚会的道路

    背景   Candy住在一个被划分为n个区域的神奇小镇中,其中Candy的家在编号为n的区域,Candy生日这天,大家都急急忙忙赶去Candy家庆祝Candy的生日. 描述   Candy共有t个朋友 ...

  3. python的str,unicode对象的encode和decode方法, Python中字符编码的总结和对比bytes和str

    python_2.x_unicode_to_str.py a = u"中文字符"; a.encode("GBK"); #打印: '\xd6\xd0\xce\xc ...

  4. sum(),max(),avg(),RATIO_TO_REPORT()--分组统计

    select id,area, sum(1) over() as 总记录数, sum(1) over(partition by id) as 分组记录数, sum(score) over() as 总 ...

  5. laravel 中使用tinker 验证驱动加载是否成功

    在验证laravel 中   InvalidArgumentException Driver [WeiBo] not supported. public function weibo() { retu ...

  6. idea使用积累

    1.初试化配置参照http://m.blog.csdn.net/robertohuang/article/details/75042116,很详细. 2.idea中忽略.idea,.iml这两个文件 ...

  7. @codeforces - 1106F@ Lunar New Year and a Recursive Sequence

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义递推数列 f: (1)f[1] = f[2] = ... f ...

  8. ListView 适配器实现getviewtypecount() 数组越界IndexOutOfBoundException

    ListView中Item的多布局显示,需要用到了getviewtypecount和getItemViewType这两个重写方法,但是做完后出现了如下提示错误: java.lang.ArrayInde ...

  9. 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 ...

  10. Android Studio(十二):打包多个发布渠道的apk文件

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...