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 ...
随机推荐
- NYOJ 298 点的变换
题目链接:298 点的变换 这题放在矩阵快速幂里,我一开始想不透它是怎么和矩阵搭上边的,然后写了个暴力的果然超时,上网看了题解后,发现竟然能够构造一些精巧的矩阵来处理,不得不说实在太强大了! http ...
- ip变更导致连接不到mysql的解决办法
第一步:ssh连接到服务器 第二步:连接mysql mysql -u root -psqj888 第三步:切换到mysql数据库 use mysql 第四步:查询mysql的user表 SELECT ...
- Java 两个变量交换值
package test; public class Test { public static void main(String[] args) { int a, b; ...
- Windows 上远程访问 Unix 的 XWindow / XManager / X
准备 下载 putty - http://www.putty.org/ 安装 cygwin - http://cygwin.com/, 并添加 e.g. c:/cygwin/bin 到 Window ...
- openfire控制台登录不了的解决
不知道为什么,openfire服务器后台,发生几次密码都登录不上去的问题,密码肯定没错,第一次就是默认的用户名:admin,密码:admin,然,第三天,说我密码错误,后来重装软件才弄好, 然后又发生 ...
- python操作mongodb之七时间和时区
#时间和时区 import datetime db.test.insert_one({"datetime-datetime-utcnow":datetime.datetime.ut ...
- 【bug】“Mat map” opencv全局变量不明确
Mat map= Mat::zeros(WIN_WIDTH, WIN_HIGH, CV_8UC3);//全局变量 int main() { map.setTo(); } Error map 不明确 s ...
- armp启动
1.启动apahcehttpd.exe -k starthttpd.exe -k restart 重启httpd.exe -k install 安装 2.php启动apache.conf文件添加:Lo ...
- K-均值聚类及其在生物信息中的应用
如果一点基础没有最好先拿起一本教材开始学,<机器学习实战>还不错,P93,书上有python源码和练习数据,非常适合新手. k均值聚类 名词:簇:相似度算法 伪代码 创建K个点作为起始质心 ...
- Perl 语法 - 基础
perl语言的核心是正则表达式,在文本处理上非常有优势,与python类似,但语法不同,perl的语法很灵活,用多了才会觉得好用. 常用知识点总结: perl语法类似于C语言(perl源于Unix), ...