Team

时间限制: 1 Sec  内存限制: 128 MB
提交: 124  解决: 10
[提交] [状态] [命题人:admin]

题目描述

ACM-ICPC is a interesting game. A team takes part in this game must consist of exactly (no more and no less) three players. Every year, many new members will join the FZU ACM team. How to form teams becomes a big problem.
There are 3N members this year. Each member has a power Wi. If three distinct members x, y, z form a team, the power of this team is the minimum value of Wx, Wy, Wz.
There are M pairs of relationship called best friend. If member A and member B are best friend, they must be in the same team.
We want to form N teams, and get the maximum sum of the power of these N teams. Can you help us?

输入

Input is given from Standard Input in the following format:
N M
W1 W2 . . . W3N
A1 B1
.
.
.
AM BM
Constraints
1≤N, M≤103
1≤Wi≤109
1≤Ai, Bi≤3N (1≤i≤M, Ai≠Bi)
All inputs are integers.

输出

If it’s possible to form N teams, print one integer denotes the maximum sum of the power of these N teams. Otherwise print -1.

样例输入

2 1
1 2 3 4 5 6
3 4

样例输出

4

题目大意:

先输入两个整数n和m,代表有n个人,m组朋友关系,下面一行输入n个整数,代表每个人的能力值,然后输入m行关系a,b,代表a和b是好朋友,现在要将他们进行分队,每队固定为3个人,并且每队的能力值为三个人中最小的能力值,即对于队伍1:a,b,c,其队伍的能力为w[a],w[b],w[c]三者的最小值,同时也规定如果a和b是朋友关系,则a,b一定要在同一个队伍里,问组成队伍的最大能力值之和。

解题思路:

首先确定的是朋友关系的一定须在同一个队伍里,所以可以先按照朋友关系先将当前的情况分为三种:一人一个队,两人一个队,三人一个队,因此可以通过并查集来实现,将为朋友关系的人放到同一个集合中,并将这个集合的权值设为集合中元素能力值的最小值,如果出现了集合中的元素大于3的情况,那么这种情况一定不成立,然后根据其集合人数将其分为1人,2人,3人三种情况,分别存在数组中。

dp[i][j]代表的是已经在一人集合中选取了i个,在两人集合中选取了j个,则若要组成一个三人小队,可以分为两种情况,选三个一人队,选一个一人一个两人队,因此可以推出动态转移方程为:

dp[i+3][j]=max(dp[i+3][j],dp[i][j]+min(v[1][i],min(v[1][i+1],v[1][i+2]));

dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+min(v[1][i],v[2][j]));

假设:一人队数组长度为len1,两人队数组长度为len2,则我们可以知道若dp[len1][len2]==0,则证明此种情况不成立,组不成全为三人队,若其不为0,则用当前的dp[len1][len2]加上三人队集合的能力值即可。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
ll w[3100];
int f[3100];
ll num[3100];
ll dp[3100][3100];
vector<ll> v[10];
bool ju;
int find(int x)
{return x==f[x]?x:find(f[x]);
}
void merge(int a,int b)
{int fa=find(a);int fb=find(b);if(fa!=fb) {if(fa<fb) {f[fb]=fa;num[fa]=num[fa]+num[fb];w[fa]=min(w[fa],w[fb]);if(num[fa]>3) ju=false;num[fb]=0;}else {f[fa]=fb;num[fb]=num[fb]+num[fa];w[fb]=min(w[fa],w[fb]);if(num[fb]>3) ju=false;num[fa]=0;}}
}
int main()
{#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endif//freopen("out.txt", "w", stdout);ios::sync_with_stdio(0),cin.tie(0);int n,m;cin>>n>>m;rep(i,1,3*n) {cin>>w[i];f[i]=i;num[i]=1;}ju=true;rep(i,1,m) {int a,b;cin>>a>>b;merge(a,b);}if(ju==false) {cout<<"-1"<<endl;return 0;}rep(i,1,3*n) {if(num[i]==1) v[1].push_back(w[i]);if(num[i]==2) v[2].push_back(w[i]);if(num[i]==3) v[3].push_back(w[i]);}int len1=v[1].size();int len2=v[2].size();int len3=v[3].size();sort(v[1].begin(),v[1].end());sort(v[2].begin(),v[2].end());sort(v[3].begin(),v[3].end());v[1].push_back(0);v[1].push_back(0);v[1].push_back(0);v[1].push_back(0);v[2].push_back(0);v[2].push_back(0);v[2].push_back(0);v[2].push_back(0);for(int i=0;i<=len1;i++) {for(int j=0;j<=len2;j++) {dp[i+3][j]=max(dp[i+3][j],dp[i][j]+v[1][i]);dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+min(v[1][i],v[2][j]));}}if(dp[len1][len2]!=0) {ll ans=dp[len1][len2];for(int i=0;i<len3;i++) ans+=v[3][i];cout<<ans<<endl;}else {cout<<"-1"<<endl;}return 0;
}

【并查集+dp】Team相关推荐

  1. POJ 1417 True Liars(路径压缩并查集+DP背包问题)

    POJ 1417 True Liars(路径压缩并查集+DP背包问题) http://poj.org/problem?id=1417 题意: 给出p1+p2个人,其中p1个是好人,p2个是坏人.然后有 ...

  2. P1455-搭配购买【图论,并查集,dp,背包】

    正题 题目链接: https://www.luogu.org/problemnew/show/P1455 大意 有n个商品,给出价值和价格.有m组搭配,如果买了其中一个就得买另一个,给出你拥有的钱,求 ...

  3. POJ 1417 True Liars(带权并查集+DP)

    传送门 Description After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda ...

  4. POJ 1417 True Liars (种类并查集+DP)

    题目:True Liars 题目大意:给出n对关系,p1个好人,p2个坏人.要求根据n对关系中找出好人有哪些,若方案唯一,则逐个输出好人,最后输出end:若方案不唯一/找不到,那么输出no 结论:通过 ...

  5. [Tarjan][并查集][dp] Jzoj P4253 QYQ在艾泽拉斯

    Description 在艾泽拉斯的无尽之海里,有着一群不为人知的由各个种族的冒险者统治的岛屿,这些岛屿都很庞大,足以在上面建造许多的城市,城市之间有一些单向道路连接. 有一天,QYQ无意中发现了这些 ...

  6. POJ 并查集 题目汇总 ——czyuan原创(转)

    继续数据结构的复习,本次的专题是:并查集. 并查集,顾名思义,干的就是"并"和"查"两件事.很多与集合相关的操作都可以用并查集高效的解决. 两个操作代码:    ...

  7. All men are brothers(并查集+思维 好题!!!)

    链接:https://ac.nowcoder.com/acm/contest/889/E 来源:牛客网 Amy asks Mr. B problem E. Please help Mr. B to s ...

  8. 【转】并查集MST题集

    转自:http://blog.csdn.net/shahdza/article/details/7779230 [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 ...

  9. [kuangbin带你飞]专题五 并查集 题解+总结

    kuangbin带你飞:点击进入新世界 总结: 本人算是初学者中的初学者,欢迎交流~ 并查集的接触过的不多,大概只有普通并查集,带权并查集,种族并查集,传说中的可持续化并查集只是听说过还没有接触,不过 ...

最新文章

  1. 几级工作台做石头高墙_创造与魔法:建筑新手入门攻略,家园建材怎么做
  2. url映射 路由urls.py的功能 django
  3. 创业几乎不要本钱,是创业圈内最大的谎言
  4. 云服务器装teamviewer
  5. OpenCV Laplacian 拉普拉斯变换
  6. BZOJ3091 城市旅行
  7. 真实网络环境下使用易邮搭建网络邮件服务器并测试通过
  8. 好工具,不私藏!介绍一个提高效率的利器
  9. 高通工具QXDM安装及使用方法
  10. Linux 快速搭建免费邮件服务器
  11. 打造现代应用的利器,VMware Tanzu显露王者风范 (1)
  12. r语言mfrow全程_R语言(绘图入门)
  13. Flask-token-werkzeufg
  14. 环游世界,走遍读过的每一个国家和城镇
  15. mysql 排除节假日_MYSQL 两日期之间的工作日(去掉周六日,不考虑节假日)_mysql...
  16. 制作多维度分组交叉销售统计表
  17. 好玩的手机淘宝社群,发单初体验
  18. Xshell安装与使用
  19. 征战希洛克集卡活动显示服务器没角色,希洛克征战模式
  20. CMU硕士101-千奇百怪的排序算法

热门文章

  1. git通过指令查看某一个已经修改的文件的改动
  2. QMap删除其中的保存的元素本身,并删除容器中保存的元素
  3. oracle修改窗口字体大小,jQuery之字体大小的设置方法
  4. linux操作系统字段含义,Linux系统 /etc/fstab各个字段含义解释
  5. Android在线更新安装包,Android在线更新下载方案
  6. android打印html页面,Android打印HTML文档
  7. android xml 列表展示,Android中ListView实现展示列表数据
  8. 登和平视显示无法连接服务器,提醒信息的推送方法和装置、平视显示器HUD及服务器...
  9. android string数字字符串如何使用科学计数法,JSONObject 偶遇 数字字符串变为科学计数法 如何变为普通数字字符串...
  10. js定位div坐标存入mysql_JavaScript与Div 对层定位和移动获得坐标