您的位置:首页 > 其它

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;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: