裸的最大流
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=2000,M=10000; 6 const int inff=1<<29; 7 int head[N],nc; 8 struct edge 9 { 10 int x,y,next; 11 int cap; 12 } edge[M*3]; 13 void add(int x,int y,int cap) 14 { 15 edge[nc].x=x; 16 edge[nc].y=y; 17 edge[nc].cap=cap; 18 edge[nc].next=head[x]; 19 head[x]=nc++; 20 edge[nc].x=y; 21 edge[nc].y=x; 22 edge[nc].cap=0; 23 edge[nc].next=head[y]; 24 head[y]=nc++; 25 } 26 int num[N],h[N],S,T,n; 27 int findpath(int x,int flow) 28 { 29 if(x==T) 30 return flow; 31 int res=flow,pos=n-1; 32 for(int i=head[x]; i!=-1; i=edge[i].next) 33 { 34 int y=edge[i].y; 35 if(h[x]==h[y]+1&&edge[i].cap>0) 36 { 37 int tp=findpath(y,min(edge[i].cap,res)); 38 res-=tp; 39 edge[i].cap-=tp; 40 edge[i^1].cap+=tp; 41 if(!res||h[S]==n) 42 return flow-res; 43 } 44 if(edge[i].cap>0&&h[y]<pos) 45 pos=h[y]; 46 } 47 if(res==flow) 48 { 49 num[h[x]]--; 50 if(num[h[x]]==0) 51 { 52 h[S]=n; 53 return flow-res; 54 } 55 h[x]=pos+1; 56 num[h[x]]++; 57 } 58 return flow-res; 59 } 60 int Sap() 61 { 62 memset(h,0,sizeof(h)); 63 memset(num,0,sizeof(num)); 64 int ans=0; 65 while(h[S]!=n) 66 ans+=findpath(S,inff); 67 return ans; 68 } 69 int main() 70 { 71 char cs[10]={"@SMLXT"}; 72 char s[20]; 73 while(scanf("%s",s)&&strcmp(s,"ENDOFINPUT")!=0) 74 { 75 int m; 76 scanf("%d",&m); 77 memset(head,-1,sizeof(head)); 78 S=nc=0;n=6;T=6+m; 79 for(int i=0;i<m;i++) 80 { 81 scanf("%s",s); 82 for(int j=1;j<=5;j++) 83 { 84 if(s[0]==cs[j]) 85 { 86 add(j,n,1); 87 while(j<=5) 88 { 89 add(j,n,1); 90 j++; 91 if(cs[j]==s[1]) 92 { 93 add(j,n,1); 94 j=10; 95 } 96 } 97 } 98 } 99 add(n++,T,1); 100 } 101 for(int j,i=1;i<=5;i++) 102 { 103 scanf("%d",&j); 104 add(0,i,j); 105 } 106 if(Sap()==m) 107 printf("T-shirts rock!\n"); 108 else 109 printf("I'd rather not wear a shirt anyway...\n"); 110 scanf("%s",s); 111 } 112 return 0; 113 }