zoukankan      html  css  js  c++  java
  • HDU 5353

     题目大意:

    相邻的朋友可以给出自己手上最多一颗糖,n个朋友形成一个环,问给的方式能否最后使所有朋友都糖的数量相同

    这里我用的是网络流来做的,这里n=100000,用sap的模板可以跑过

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cstring>
      5 using namespace std;
      6 #define ll long long
      7 const int MAXN = 100010;
      8 const int MAXM = 400010;
      9 const int INF = 0x3f3f3f3f;
     10 struct Edge{
     11     int st , to ,  next, cap , flow;
     12 }edge[MAXM];
     13 
     14 int tol , head[MAXN] , gap[MAXN] , dep[MAXN] , cur[MAXN];
     15 
     16 void init(){
     17     tol = 0;
     18     memset(head , -1  , sizeof(head));
     19 }
     20 
     21 void add_edge(int u , int v , int w , int rw=0)
     22 {
     23     edge[tol].st = u , edge[tol].to=v , edge[tol].cap = w , edge[tol].flow=0;
     24     edge[tol].next = head[u] , head[u] = tol++;
     25 
     26     edge[tol].st = v , edge[tol].to = u , edge[tol].cap = rw , edge[tol].flow=0;
     27     edge[tol].next = head[v] , head[v] = tol++;
     28 }
     29 
     30 int Q[MAXN];
     31 
     32 void BFS(int start , int end)
     33 {
     34     memset(dep , -1 , sizeof(dep));
     35     memset(gap , 0 , sizeof(gap));
     36     gap[0] = 1;
     37     int front = 0 , rear = 0;
     38     dep[end] = 0;
     39     Q[rear++] = end;
     40     while(front != rear){
     41         int u  = Q[front++];
     42         for(int i=head[u] ; i!=-1 ; i=edge[i].next){
     43             int v = edge[i].to ;
     44             if(dep[v]!=-1) continue;
     45             Q[rear++] = v;
     46             dep[v] = dep[u] + 1;
     47             gap[dep[v]]++;
     48         }
     49     }
     50 }
     51 
     52 int S[MAXN];
     53 int sap(int start , int end , int N)
     54 {
     55     BFS(start , end);
     56     memcpy(cur , head , sizeof(head));
     57     int top=0;
     58     int u=start;
     59     int ans = 0;
     60     while(dep[start]<N)
     61     {
     62         if(u == end){
     63             int Min = INF;
     64             int inser;
     65             for(int i=0 ; i<top ; i++)
     66                 if(Min>edge[S[i]].cap-edge[S[i]].flow){
     67                     Min = edge[S[i]].cap-edge[S[i]].flow;
     68                     inser = i;
     69                 }
     70             for(int i=0 ; i<top ; i++){
     71                 edge[S[i]].flow+=Min;
     72                 edge[S[i]^1].flow-=Min;
     73             }
     74             ans+=Min;
     75             top = inser;
     76             u = edge[S[top]^1].to;
     77             continue;
     78         }
     79         bool flag = false;
     80         int v ;
     81         for(int i=cur[u] ; i!=-1 ; i=edge[i].next){
     82             v = edge[i].to;
     83             if(edge[i].cap-edge[i].flow && dep[v]+1==dep[u]){
     84                 flag = true;
     85                 cur[u] = i;
     86                 break;
     87             }
     88         }
     89         if(flag){
     90             S[top++] = cur[u];
     91             u = v;
     92             continue;
     93         }
     94         int Min = N;
     95         for(int i=head[u] ; i!=-1 ; i=edge[i].next){
     96             if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min){
     97                 Min = dep[edge[i].to];
     98                 cur[u] = i;
     99             }
    100         }
    101         gap[dep[u]]--;
    102         if(!gap[dep[u]]) return ans;
    103         dep[u] = Min+1;
    104         gap[dep[u]]++;
    105         if(u != start) u = edge[S[--top]^1].to;
    106     }
    107     return ans;
    108 }
    109 int n , m , val[MAXN] , id[MAXN] , in[MAXN] , out[MAXN] , x,  y , fl;
    110 ll sum , ave;
    111 int main()
    112 {
    113   // freopen("in.txt" , "r" , stdin);
    114     int cas;
    115     scanf("%d",&cas);
    116     while(cas--){
    117         init();
    118         scanf("%d" , &n);
    119         sum = 0;
    120         for(int i=1 ; i<=n ; i++){
    121             scanf("%d" , val+i);
    122             sum+=val[i];
    123         }
    124         bool ok = true;
    125         if(sum%n != 0){
    126             ok = false;
    127         }
    128         if(!ok){
    129             puts("NO");
    130             continue;
    131         }
    132         ave = sum/n;
    133         for(int i=1 ; i<=n ; i++){
    134             if(abs(val[i]-ave)>2) ok = false;
    135         }
    136         if(!ok){
    137             puts("NO");
    138             continue;
    139         }
    140         add_edge(n , 1 , 1 , 1);
    141         for(int i=2 ; i<=n ; i++){
    142             add_edge(i , i-1 , 1 , 1);
    143         }
    144         int min_flow = 0;
    145         for(int i=1 ; i<=n ; i++){
    146             if(val[i]>ave){
    147                 add_edge(0 , i , val[i]-ave);
    148             }
    149             else if(val[i]<ave){
    150                 add_edge(i , n+1 , ave-val[i]);
    151                 min_flow+=ave-val[i];
    152             }
    153         }
    154         int flow = sap(0 ,n+1 , n+2);
    155       //  cout<<flow<<" "<<min_flow<<endl;
    156         if(flow!=min_flow) ok = false;
    157         if(!ok){
    158             puts("NO");
    159             continue;
    160         }
    161         int rec[MAXN][2] , tot=0;
    162         for(int i=0 ; i<tol ; i+=2){
    163             if(edge[i].st>=1 && edge[i].to<=n){
    164                 /*if(edge[i].flow + edge[i^1].flow == 0){
    165                     cout<<edge[i].st<<" "<<edge[i].to<<endl;
    166                     cout<<edge[i^1].st<<" "<<edge[i^1].to<<endl;
    167                     continue;
    168                 }*/
    169                 if(edge[i].flow>0) rec[tot][0] = edge[i].st , rec[tot++][1] = edge[i].to;
    170                 else if(edge[i^1].flow>0) rec[tot][0] = edge[i^1].st , rec[tot++][1] = edge[i^1].to;
    171             }
    172         }
    173         printf("YES
    %d
    " , tot);
    174         for(int i=0 ; i<tot ; i++) printf("%d %d
    " , rec[i][0] , rec[i][1]);
    175     }
    176     return 0;
    177 }
  • 相关阅读:
    解决word启动时报找不到mathpage.wll错误
    单应性(homography)变换的推导
    深度残差网(deep residual networks)的训练过程
    《OpenCV3 计算机视觉--Python语言实现 第二版》源代码及纠错
    jquery版结婚电子请帖
    jquery版小型婚礼(可动态添加祝福语)
    OOP感想
    前端笔试题解答
    jquery版瀑布流
    jquery版时钟(css3实现)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4720407.html
Copyright © 2011-2022 走看看