ACM: 动态规划题 poj 3140

来源:互联网 发布:金山tw域名遭抢注 编辑:程序博客网 时间:2024/06/08 03:01
ContestantsDivision
Description

In the new ACM-ICPC RegionalContest, 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 newjudging system, the organizing committee can only afford to set thesystem up such that there will be only one way to transferinformation from one university to another without passing the sameuniversity twice. The contestants will be divided into twoconnected regions, and the difference between the total numbers ofstudents from two regions should be minimized. Can you help thejuries to find the minimum difference?

Input

There are multiple testcases in the input file. Each test case starts with two integersN and M, (1 ≤ N ≤ 100000, 1 ≤ M ≤1000000), the number of universities and the number of directcommunication line set up by the committee, respectively.Universities are numbered from 1 to N. The next line hasN integers, the Kth integer is equal tothe number of students in university numbered K. The numberof students in any university does not exceed 100000000. Each ofthe following M lines has two integers s, t,and describes a communication line connecting university sand university t. All communication lines of this new systemare bidirectional.

N = 0, M = 0 indicates the end of input and shouldnot be processed by your program.

Output

For every test case, output one integer, the minimum absolutedifference of students between two regions in the format asindicated 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;
}


 

0 0
原创粉丝点击