枚举每个数字是否能被删去,然后就是如何判定图是否存在。应该从按“度数”从大到小排序,从最大的顺次向其他点连边(先连“度数”小的可能会把一些可以和大“度数”点连接的点用掉)。但是这个排序每连一次都要做一次,而$N<=500$的情况下$O(n^3log$ $n)$并不能过。但是发现度数最多只有$n$,所以可以桶排,水过=。=
USACO官方题解说可以再套一个数据结构变成$O(n^2log$ $n)$,然而并不会做
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=505; 6 int deg[N],bkt[N],mem[N]; 7 int tmp[N],outp[N]; 8 int n,p,cnt; 9 int main () 10 { 11 scanf("%d",&n); 12 register int i,j,k; 13 for(i=1;i<=n+1;i++) 14 scanf("%d",°[i]); 15 for(i=1;i<=n+1;i++) 16 { 17 bool flag=true; 18 for(j=1;j<=n+1;j++) 19 tmp[j]=(i==j)?0:deg[j]; 20 for(j=1;j<=n+1;j++) 21 { 22 memset(bkt,0,sizeof bkt),p=0; 23 for(k=j+1;k<=n+1;k++) bkt[tmp[k]]++; 24 for(k=n;~k;k--) while(bkt[k]) mem[++p]=k,bkt[k]--; 25 for(k=1;k<=n-j+1;k++) tmp[j+k]=mem[k]; 26 for(k=j+1;k<=n+1&&tmp[j];k++) 27 if(tmp[k]) tmp[k]--,tmp[j]--; 28 } 29 for(j=1;j<=n+1;j++) 30 if(tmp[j]) {flag=false; break;} 31 if(flag) outp[++cnt]=i; 32 } 33 sort(outp+1,outp+1+cnt); 34 printf("%d\n",cnt); 35 for(i=1;i<=cnt;i++) 36 printf("%d\n",outp[i]); 37 return 0; 38 }