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 ...
随机推荐
- 基础4 Android基础
基础4 Android基础 1. Activity与Fragment的生命周期. Activity生命周期 打开应用 onCreate()->onStart()->onResume 按BA ...
- Android Glide+CircleImageView实现加载圆形图片列表
需求:要在列表中实现圆形图片的显示,控件可能和加载库会存在冲突 先上代码,至于其中源码,以后有空再分析 MainActivity public class MainActivity extends A ...
- JavaScript 开发进阶:理解 JavaScript 作用域和作用域链(转载 学习中。。。)
作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...
- Android lint 删除无用图片文件和配置文件
Android lint 删除无用.冗余的 配置文件和 图片资源 转载请注明 http://blog.csdn.net/aaawqqq?viewmode=contents Android项 ...
- 使用火狐的restclient发送http接口post及get请求
1.在firefox安装restclient插件,具体参照http://jingyan.baidu.com/article/1876c8529b07e3890b137623.html: —.发送pos ...
- python语法笔记(六)
1.序列的方法 python中序列包含列表list.元组tuple.字符串str. 可以用于序列(表.元组.字符串)的内建函数: len(s) 返回: 序列中包含元素的个数 min(s) 返回 ...
- double精度问题,数据范围
浮点数在计算机中存储方式 http://www.cnblogs.com/jillzhang/archive/2007/06/24/793901.html 1. double: 1bit(符号位) ...
- python 图实现
#coding:utf-8 __author__ = 'similarface' class Graph: def __init__(self,label,extra=None): #节点是类实例 s ...
- matlab中图像显示函数
image函数是显示图像的最基本的方法.该函数还产生了图像对象的句柄,并允许对对象的属性进行设置. imagesc函数也具有image的功能,所不同的是imagesc函数还自动将输入数据比例化,以全色 ...
- 清理无用的CSS样式的几个工具(转)
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...