1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; const int N=510,FSIZE=1<<26,INF=0x7f7f7f7f; int tn,n,cur[N],a[N],sze,d[N],w[N],p0[N],p1[N],is[N][N],c[N][N]; struct{int n,t,v;}b[N*N]; char BuF[FSIZE],*InF=BuF; template<typename T>void read(T &x){ for(;48>*InF||*InF>57;++InF); for(x=0;47<*InF&&*InF<58;x=x*10+(*InF++^48)); } void _add(int x,int y,int z){ b[sze++]={a[x],y,z}; a[x]=sze-1; } void add(int x,int y,int z){ _add(x,y,z); _add(y,x,0); } bool bfs(){ memset(w,127,sizeof(w)); for(int h=w[0]=0,t=d[0]=0;h<=t;++h) for(int i=cur[d[h]]=a[d[h]];~i;i=b[i].n) if(b[i].v&&w[b[i].t]>w[d[h]]+1) w[d[++t]=b[i].t]=w[d[h]]+1; return(w[n+n+1]<INF); } int dfs(int x,int flow){ if(x==n+n+1) return(flow); int used=0,aflow; for(int &i=cur[x];~i;i=b[i].n) if(w[b[i].t]==w[x]+1&&b[i].v&&(aflow=dfs(b[i].t,min(b[i].v,flow)))){ b[i].v-=aflow; b[i^1].v+=aflow; if((used+=aflow)==flow) break; } return(used); } int dinic(){ int re=0; for(;bfs();re+=dfs(0,INF)); return(re); } void work(){ memset(a,-1,sizeof(a)); sze=0; read(n); for(int i=1;i<=n;++i){ add(0,i,0); p0[i]=sze-2; add(i+n,n+n+1,0); p1[i]=sze-2; for(int j=1,x;j<=n;++j){ read(x); add(i,x+n,1); c[i][j]=sze-2; } } for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ b[p0[j]].v=1; b[p0[j]^1].v=0; b[p1[j]].v=1; b[p1[j]^1].v=0; } dinic(); for(int j=1;j<=n;++j) for(int k=1;k<=n;++k) if(b[c[j][k]^1].v){ is[j][i]=k; b[c[j][k]^1].v=0; } } printf("%d\n",n*(n-1)>>1); for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) printf("%d %d %d %d\n",i,is[i][j],j,is[j][i]); } int main(){ fread(BuF,1,FSIZE,stdin); for(read(tn);tn--;work()); return(0); }
|