ACM: 动态规划题 poj 3140
2016-05-19 23:25
363 查看
Contestants
Division
Description
In the new ACM-ICPC Regional
Contest, a special monitoring and submitting system will be set up,
and students will be able to compete at their own universities.
However there’s one problem. Due to the high cost of the new
judging system, the organizing committee can only afford to set the
system up such that there will be only one way to transfer
information from one university to another without passing the same
university twice. The contestants will be divided into two
connected regions, and the difference between the total numbers of
students from two regions should be minimized. Can you help the
juries to find the minimum difference?
Input
There are multiple test
cases in the input file. Each test case starts with two integers
N and M, (1 ≤ N ≤ 100000, 1 ≤ M ≤
1000000), the number of universities and the number of direct
communication line set up by the committee, respectively.
Universities are numbered from 1 to N. The next line has
N integers, the Kth integer is equal to
the number of students in university numbered K. The number
of students in any university does not exceed 100000000. Each of
the following M lines has two integers s, t,
and describes a communication line connecting university s
and university t. All communication lines of this new system
are bidirectional.
N = 0, M = 0 indicates the end of input and should
not be processed by your program.
Output
For every test case, output one integer, the minimum absolute
difference of students between two regions in the format as
indicated in the sample output.
Sample Input
7 6
1 1 1 1 1 1 1
1 2
2 7
3 7
4 6
6 2
5 7
0 0
Sample Output
Case 1: 1
题意: ACM举办方要将全部参赛的学校分成2部分, 要求2部分的人分配尽量平均, 求出最小差值.
解题思路:
1. 题目很简单, 但是错误多多. 设状态dp[i]: 以i为根的子树, 全部人数和.
结果: result = min(result, | sum-dp[i]*2 | );
2. 人数总和会超出int范围, 在这里WA了几次.
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define MAX 200005
const __int64 temp = 1;
const __int64 INF = (temp<<61);
int n, m;
vector<int> g[MAX];
__int64 a[MAX];
__int64 dp[MAX], sum;
bool vis[MAX];
inline __int64 my_abs(__int64 a)
{
return a > 0 ? a : (-a);
}
inline __int64 min(__int64 a, __int64 b)
{
return a < b ? a : b;
}
void dfs(int u)
{
vis[u] = true;
dp[u] = a[u];
for(int i = 0; i < g[u].size();
++i)
{
if(vis[ g[u][i] ])
continue;
dfs(g[u][i]);
dp[u] += dp[ g[u][i] ];
}
}
__int64 solve()
{
__int64 result = INF;
for(int i = 1; i <= n; ++i)
{
for(int v = 0; v
< g[i].size(); ++v)
{
result =
min(result, my_abs(dp[ g[i][v] ]*2-sum));
}
}
return result;
}
int main()
{
int i, u, v;
int num = 1;
// freopen("input.txt", "r", stdin);
while(scanf("%d %d",&n,
&m) != EOF)
{
if(n == 0
&& m == 0) break;
sum = 0;
memset(dp, 0,
sizeof(dp));
memset(vis, false,
sizeof(vis));
for(i = 1; i <=
n; ++i)
{
scanf("%I64d",&a[i]);
sum +=
a[i];
g[i].clear();
}
if(n == 1)
{
printf("Case
%d: %d\n",num++,a[1]);
continue;
}
for(i = 1; i
<= m; ++i)
{
scanf("%d
%d",&u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1);
printf("Case %d:
%I64d\n",num++, solve());
}
return 0;
}
Division
Description
In the new ACM-ICPC Regional
Contest, a special monitoring and submitting system will be set up,
and students will be able to compete at their own universities.
However there’s one problem. Due to the high cost of the new
judging system, the organizing committee can only afford to set the
system up such that there will be only one way to transfer
information from one university to another without passing the same
university twice. The contestants will be divided into two
connected regions, and the difference between the total numbers of
students from two regions should be minimized. Can you help the
juries to find the minimum difference?
Input
There are multiple test
cases in the input file. Each test case starts with two integers
N and M, (1 ≤ N ≤ 100000, 1 ≤ M ≤
1000000), the number of universities and the number of direct
communication line set up by the committee, respectively.
Universities are numbered from 1 to N. The next line has
N integers, the Kth integer is equal to
the number of students in university numbered K. The number
of students in any university does not exceed 100000000. Each of
the following M lines has two integers s, t,
and describes a communication line connecting university s
and university t. All communication lines of this new system
are bidirectional.
N = 0, M = 0 indicates the end of input and should
not be processed by your program.
Output
For every test case, output one integer, the minimum absolute
difference of students between two regions in the format as
indicated in the sample output.
Sample Input
7 6
1 1 1 1 1 1 1
1 2
2 7
3 7
4 6
6 2
5 7
0 0
Sample Output
Case 1: 1
题意: ACM举办方要将全部参赛的学校分成2部分, 要求2部分的人分配尽量平均, 求出最小差值.
解题思路:
1. 题目很简单, 但是错误多多. 设状态dp[i]: 以i为根的子树, 全部人数和.
结果: result = min(result, | sum-dp[i]*2 | );
2. 人数总和会超出int范围, 在这里WA了几次.
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define MAX 200005
const __int64 temp = 1;
const __int64 INF = (temp<<61);
int n, m;
vector<int> g[MAX];
__int64 a[MAX];
__int64 dp[MAX], sum;
bool vis[MAX];
inline __int64 my_abs(__int64 a)
{
return a > 0 ? a : (-a);
}
inline __int64 min(__int64 a, __int64 b)
{
return a < b ? a : b;
}
void dfs(int u)
{
vis[u] = true;
dp[u] = a[u];
for(int i = 0; i < g[u].size();
++i)
{
if(vis[ g[u][i] ])
continue;
dfs(g[u][i]);
dp[u] += dp[ g[u][i] ];
}
}
__int64 solve()
{
__int64 result = INF;
for(int i = 1; i <= n; ++i)
{
for(int v = 0; v
< g[i].size(); ++v)
{
result =
min(result, my_abs(dp[ g[i][v] ]*2-sum));
}
}
return result;
}
int main()
{
int i, u, v;
int num = 1;
// freopen("input.txt", "r", stdin);
while(scanf("%d %d",&n,
&m) != EOF)
{
if(n == 0
&& m == 0) break;
sum = 0;
memset(dp, 0,
sizeof(dp));
memset(vis, false,
sizeof(vis));
for(i = 1; i <=
n; ++i)
{
scanf("%I64d",&a[i]);
sum +=
a[i];
g[i].clear();
}
if(n == 1)
{
printf("Case
%d: %d\n",num++,a[1]);
continue;
}
for(i = 1; i
<= m; ++i)
{
scanf("%d
%d",&u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1);
printf("Case %d:
%I64d\n",num++, solve());
}
return 0;
}
相关文章推荐
- ACM: 动态规划题 poj 2486
- ACM: 动态规划题 poj 1947
- ACM: 动态规划题 poj 2057 树状DP
- ACM: 动态规划题 poj 1185 想了两…
- 兴趣学习: 摆脱“三天打渔两天晒网”…
- ACM: 动态规划题 poj 2411
- ACM: 动态规划题 poj 3254 学习状…
- ES使用脚本进行局部更新的排错记录 推荐
- ACM: 动态规划题 poj 3034
- (OK)(OK) Fedora23——NS3(MANETs)——Docker(busybox)——genymotion(android)——All is OK
- windows.h
- ACM: 动态规划题 poj 1925
- ACM: 动态规划题 poj 2948
- ACM: 树状数组 poj 2029 动态规划…
- ACM: 动态规划题 poj3280
- ACM: 动态规划题 poj 1054
- ACM: 并查集 poj 2492
- 兴趣学习: 信息熵 ---- 《数学…
- ACM: 并查集 poj 1703
- ACM: 线段树 poj 3368