dinic80分求助

P2055 [ZJOI2009] 假期的宿舍

加了俩特判之后过了 感觉太离谱了 一个是特判外来人员一个人都不认识 直接T_T 一个是特判可以使用的床数小于要睡觉的人数 直接T_T 为啥我的dinic跑不出来这俩种情况T_T ``` #include<cstdio> #include<iostream> #include<cstring> using namespace std; int n,m,S,T; const int N=30000,M=100010,inf=1e8; int e[M],ne[M],f[M]; int q[N],h[N],cur[N],d[N],idx; void add(int a,int b,int c) { e[idx]=b,f[idx]=c,ne[idx]=h[a],h[a]=idx++; e[idx]=a,f[idx]=0,ne[idx]=h[b],h[b]=idx++; } bool bfs() { int tt=0,hh=0; memset(d,-1,sizeof d); q[0]=S,d[S]=0,cur[S]=h[S]; while(hh<=tt) { int t=q[hh++]; for(int i=h[t];~i;i=ne[i]) { int ver=e[i]; if(d[ver]==-1&&f[i]) { d[ver]=d[t]+1; cur[ver]=h[ver]; if(ver==T) return true; q[++tt]=ver; } } } return false; } int find(int u,int limits) { if(u==T) return limits; int flow=0; for(int i=cur[u];~i&&flow<limits;i=ne[i]) { int ver=e[i]; cur[u]=i; if(d[ver]==d[u]+1&&f[i]) { int t=find(ver,min(f[i],limits-flow)); if(!t) d[ver]=-1; f[i]-=t; f[i^1]+=t; flow+=t; } } return flow; } int dinic() { int ans=0,flow; while(bfs()) { while(flow=find(S,inf)) ans+=flow; } return ans; } int t,is[100],x[51]; bool st[51]; int main() { cin>>t; S=0,T=2*n+1; while(t--) { idx=0; cin>>n; memset(h,-1,sizeof h); memset(st,0,sizeof st); for(int i=1;i<=n;i++) { cin>>is[i]; if(is[i])//只要是学生就把自己的床向汇点建边 { add(i+n,T,1);//床向汇点建边 } } int tot=0,now=0; for(int i=1;i<=n;i++) { cin>>x[i]; if(is[i]) { if(x[i]==0)//是学生且不回家 { add(S,i,1);//源点向不回家学生建边 add(i,i+n,1);//自己可以睡自己的床 tot++; now++; st[i]=1; } } else//不是学生 { add(S,i,1);//源点向外来的亲戚朋友建边 tot++; } } int re[51][51]; memset(re,0,sizeof re); for(int i=1;i<=n;i++) { int ok=0; for(int j=1;j<=n;j++) { cin>>re[i][j]; if(re[i][j])//如果认识 { if(is[i]&&!is[j]) { add(j,i+n,1); if(!st[i]&&x[i]) now++,st[i]=1; }//i是学生j不是,j可以睡i的床 else if(!is[i]&&is[j]) { add(i,j+n,1);//j是学生i不是,i可以睡j的床 if(!st[j]&&x[j]) now++,st[j]=1; } else if(is[i]&&is[j]) { add(i,j+n,1),add(j,i+n,1);//可以相互睡 if(!x[i]&&x[j]) now++,st[j]=1; else if(x[i]&&!x[j]) now++,st[i]=1; } } } } int ff=0; for(int i=1;i<=n;i++) { if(!is[i]) { bool ok=0; for(int j=1;j<=n;j++) { if(re[i][j]) ok=1; } if(!ok) { ff=1; break; } } } if(ff) { printf("T_T\n"); continue; } if(tot>dinic()||now<tot)printf("T_T\n"); else printf("^_^\n"); memset(q,0,sizeof q); memset(cur,0,sizeof cur); memset(f,0,sizeof f); } return 0; } ```
by watasky @ 2022-07-13 15:53:00


可以试一下这组数据 ```cpp 1 6 0 0 1 1 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 ```
by llzzxx712 @ 2022-11-16 15:59:00


|