题解:
网络流
然后似乎反着做块?
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=405; int T,qq[8],vvis,q[N*10],n,m,t,l,sum,dis[N],x,y,ans,f[N],z,a[N][N]; int bfs() { memset(dis,0xff,sizeof dis); dis[n]=0; int l=0,r=1; q[1]=n; while (l<r) { int j=q[++l]; for (int i=1;i<=n;i++) if (dis[i]<0&&a[i][j]>0) { dis[i]=dis[j]+1; q[++r]=i; } if (j==1)return 1; } return 0; } int dfs(int x,int y) { if (x==n)return y; int tmp=y,t; for (int i=1;i<=n&&tmp;i++) if (dis[i]+1==dis[x]&&a[x][i]) { t=dfs(i,min(a[x][i],tmp)); a[x][i]-=t; a[i][x]+=t; tmp-=t; } return y-tmp; } int main() { scanf("%d",&T); while (T--) { vvis=0; scanf("%d",&n); memset(a,0,sizeof a); for (int k=1;k<=n;k++) { for (int i=0;i<7;i++)scanf("%d",&qq[i]); scanf("%d%d",&t,&l); vvis+=t; for (int j=0;j<7;j++) if (qq[j])for (int i=0;i<l;i++)a[351+k][i*7+j+2]=1; a[1][k+351]=t; } for (int i=2;i<=351;i++)a[i][372]=1; n=372; ans=0;int t; while (bfs())ans+=dfs(1,1e9); if (ans==vvis)puts("Yes"); else puts("No"); } }