题目大意:
相邻的朋友可以给出自己手上最多一颗糖,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\n%d\n" , tot); 174 for(int i=0 ; i<tot ; i++) printf("%d %d\n" , rec[i][0] , rec[i][1]); 175 } 176 return 0; 177 }
我还在坚持,我还未达到我所想,梦~~一直在