为什么我在自己演自己啊, 加了个特判结果下一次正确的时候没有把图清空, 找了半天bug。
先枚举一条边的状态就能推出全部, 输出过程用拓扑排序。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;} mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int n, a[N]; int tmp[N]; vector<int> G[N]; vector<PII> ret; int deg[N]; LL ave; int b[N]; bool dfs(int u, int op) { int nex = (u + 1) % n; if(nex) { if(op == -1) { a[nex]++; a[u]--; G[u].push_back(nex); deg[nex]++; if(a[nex] == ave) return dfs(nex, 0); else if(a[nex] == ave + 1) return dfs(nex, -1); else if(a[nex] == ave - 1) return dfs(nex, 1); else return false; } else if(op == 0) { if(a[nex] == ave) return dfs(nex, 0); else if(a[nex] == ave + 1) return dfs(nex, -1); else if(a[nex] == ave - 1) return dfs(nex, 1); else return false; } else if(op == 1) { a[nex]--; a[u]++; G[nex].push_back(u); deg[u]++; if(a[nex] == ave) return dfs(nex, 0); else if(a[nex] == ave + 1) return dfs(nex, -1); else if(a[nex] == ave - 1) return dfs(nex, 1); else return false; } } else { if(op == -1) { a[nex]++; a[u]--; G[u].push_back(nex); deg[nex]++; } else if(op == 1) { a[nex]--; a[u]++; G[nex].push_back(u); deg[u]++; } return a[nex] == ave; } } bool solve() { ave = 0; for(int i = 0; i < n; i++) { ave += a[i]; } if(ave % n) return false; ave /= n; for(int i = 0; i < n; i++) { if(abs(a[i] - ave) > 2) { return false; } } bool flag = false; for(int op = -1; op <= 1; op++) { for(int i = 0; i < n; i++) { a[i] = tmp[i]; G[i].clear(); deg[i] = 0; } if(dfs(0, op)) { flag = true; break; } } return flag; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); ret.clear(); for(int i = 0; i < n; i++) { deg[i] = 0; G[i].clear(); scanf("%d", &a[i]); tmp[i] = a[i]; } if(!solve()) { puts("NO"); continue; } queue<int> que; for(int i = 0; i < n; i++) { if(!deg[i]) { que.push(i); } } for(int i = 0; i < n; i++) b[i] = tmp[i]; while(!que.empty()) { int u = que.front(); que.pop(); for(auto &v : G[u]) { deg[v]--; ret.push_back(mk(u, v)); b[u]--; b[v]++; if(!deg[v]) { que.push(v); } } } puts("YES"); printf("%d ", SZ(ret)); for(auto &t : ret) { printf("%d %d ", t.fi + 1, t.se + 1); } } return 0; } /* */