HDU 5353
题目大意:
相邻的朋友可以给出自己手上最多一颗糖,n个朋友形成一个环,问给的方式能否最后使所有朋友都糖的数量相同
这里我用的是网络流来做的,这里n=100000,用sap的模板可以跑过
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define ll long long
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge{
int st , to , next, cap , flow;
}edge[MAXM]; int tol , head[MAXN] , gap[MAXN] , dep[MAXN] , cur[MAXN]; void init(){
tol = ;
memset(head , - , sizeof(head));
} void add_edge(int u , int v , int w , int rw=)
{
edge[tol].st = u , edge[tol].to=v , edge[tol].cap = w , edge[tol].flow=;
edge[tol].next = head[u] , head[u] = tol++; edge[tol].st = v , edge[tol].to = u , edge[tol].cap = rw , edge[tol].flow=;
edge[tol].next = head[v] , head[v] = tol++;
} int Q[MAXN]; void BFS(int start , int end)
{
memset(dep , - , sizeof(dep));
memset(gap , , sizeof(gap));
gap[] = ;
int front = , rear = ;
dep[end] = ;
Q[rear++] = end;
while(front != rear){
int u = Q[front++];
for(int i=head[u] ; i!=- ; i=edge[i].next){
int v = edge[i].to ;
if(dep[v]!=-) continue;
Q[rear++] = v;
dep[v] = dep[u] + ;
gap[dep[v]]++;
}
}
} int S[MAXN];
int sap(int start , int end , int N)
{
BFS(start , end);
memcpy(cur , head , sizeof(head));
int top=;
int u=start;
int ans = ;
while(dep[start]<N)
{
if(u == end){
int Min = INF;
int inser;
for(int i= ; i<top ; i++)
if(Min>edge[S[i]].cap-edge[S[i]].flow){
Min = edge[S[i]].cap-edge[S[i]].flow;
inser = i;
}
for(int i= ; i<top ; i++){
edge[S[i]].flow+=Min;
edge[S[i]^].flow-=Min;
}
ans+=Min;
top = inser;
u = edge[S[top]^].to;
continue;
}
bool flag = false;
int v ;
for(int i=cur[u] ; i!=- ; i=edge[i].next){
v = edge[i].to;
if(edge[i].cap-edge[i].flow && dep[v]+==dep[u]){
flag = true;
cur[u] = i;
break;
}
}
if(flag){
S[top++] = cur[u];
u = v;
continue;
}
int Min = N;
for(int i=head[u] ; i!=- ; i=edge[i].next){
if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min){
Min = dep[edge[i].to];
cur[u] = i;
}
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min+;
gap[dep[u]]++;
if(u != start) u = edge[S[--top]^].to;
}
return ans;
}
int n , m , val[MAXN] , id[MAXN] , in[MAXN] , out[MAXN] , x, y , fl;
ll sum , ave;
int main()
{
// freopen("in.txt" , "r" , stdin);
int cas;
scanf("%d",&cas);
while(cas--){
init();
scanf("%d" , &n);
sum = ;
for(int i= ; i<=n ; i++){
scanf("%d" , val+i);
sum+=val[i];
}
bool ok = true;
if(sum%n != ){
ok = false;
}
if(!ok){
puts("NO");
continue;
}
ave = sum/n;
for(int i= ; i<=n ; i++){
if(abs(val[i]-ave)>) ok = false;
}
if(!ok){
puts("NO");
continue;
}
add_edge(n , , , );
for(int i= ; i<=n ; i++){
add_edge(i , i- , , );
}
int min_flow = ;
for(int i= ; i<=n ; i++){
if(val[i]>ave){
add_edge( , i , val[i]-ave);
}
else if(val[i]<ave){
add_edge(i , n+ , ave-val[i]);
min_flow+=ave-val[i];
}
}
int flow = sap( ,n+ , n+);
// cout<<flow<<" "<<min_flow<<endl;
if(flow!=min_flow) ok = false;
if(!ok){
puts("NO");
continue;
}
int rec[MAXN][] , tot=;
for(int i= ; i<tol ; i+=){
if(edge[i].st>= && edge[i].to<=n){
/*if(edge[i].flow + edge[i^1].flow == 0){
cout<<edge[i].st<<" "<<edge[i].to<<endl;
cout<<edge[i^1].st<<" "<<edge[i^1].to<<endl;
continue;
}*/
if(edge[i].flow>) rec[tot][] = edge[i].st , rec[tot++][] = edge[i].to;
else if(edge[i^].flow>) rec[tot][] = edge[i^].st , rec[tot++][] = edge[i^].to;
}
}
printf("YES\n%d\n" , tot);
for(int i= ; i<tot ; i++) printf("%d %d\n" , rec[i][] , rec[i][]);
}
return ;
}
HDU 5353的更多相关文章
- 2015多校第6场 HDU 5353 Average 贪心,细节处理
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5353 题意:有n个人围城一个环,每一个人手里都有一些糖果,第i个人有ai块.现在有三种操作:第i个人给 ...
- HDU 5353 Average 糖果分配(模拟,图)
题意:有n个人坐在圆桌上,每个人带着糖果若干,每次只能给旁边的人1科糖果,而且坐相邻的两个人最多只能给一次(要么你给我,要么我给你),问是否能将糖果平均分了. 思路: 明显每个人最多只能多于平均值2个 ...
- HDU 5353—— Average——————【贪心+枚举】
Average Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total S ...
- HDU 5353 Average
Problem Description There are n soda sitting around a round table. soda are numbered from 1 to n and ...
- HDU 5353 Average 贪心
就是贪心啊,不知道为啥总是不过,总是WA 方法不对吗? 将数组扩展一倍,从左到右扫描,大于平均数就给右边的,小于就从右边拿,等于就不变,记录下操作类型. 大于2直接NO,不知道哪错了,自己出了一些数据 ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
随机推荐
- SecureCRT设置
SecureCRT设置 文章来源:http://blog.csdn.net/dongqinliuzi/article/details/39890569 本文主要介绍SecureCRT的使用方法和技巧. ...
- 转!!Java中关于Null的9个解释(Java Null详解)
对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...
- 转载 uboot 命令
1.bootm bootm [addr [arg ...]] - boot application image stored in memory passing arguments 'arg ...' ...
- hiho_1051_补提交卡
题目大意 给出1到100这100个数中的某些数字(各个数字不同),这些数字形成一个个间断的连续区间,向1-100中添加M个数字,使得添加后1-100中某连续区间的长度最大,求出添加M个数字后,最长的连 ...
- return 还是 不return
jQuery.fn.functiona = function() { //return this.each(function() { **** } jQuery(this).css('backgrou ...
- grub4dos通用菜单及相关工具包
grub4dos通用菜单及相关工具包 全套工具包(含PE.ISO,可根据需要替换删减):http://pan.baidu.com/s/1i4EjWod模板文件3.3M(不含PE.ISO):http:/ ...
- XP系统电脑带安卓手机上网教程(无需adhoc补丁)
XP系统电脑带安卓手机上网教程(无需adhoc补丁) WIN7系统可以虚拟wifi热点,安卓手机连上这个热点就能上网.XP系统虚拟出来的wifi热点是adhoc形式的,原生的安卓系统并不支持adhoc ...
- VC++ 中使用 std::string 转换字符串编码
目录 第1章说明 1 1.1 代码 1 1.2 使用 4 第1章说明 VC++中宽窄字符串的相互转换比较麻烦,借助std::string能大大减少代码量. 1.1 代码 函数声明如下 ...
- $(document).ready(function (){}) , $(function(){}) , $().ready(function(){}) , jquery(function(){}) , (function($){})(jquery)有什么区别
$(document).ready(function(){...}) , $().ready(function(){...}) , $(function(){...}) , jquery(funct ...
- 5月23日 JavaScript
一.JavaScript简介 1.JavaScript是什么: 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它的用法: 在HTML中位置有三块: (1)head里面 (2)bod ...