最小割。。S和1连边,T和0连边,再连u和v,容量均为1(怎么有二分图的味道。。)
不过一开始是想要拆点乱搞,然后发现边好像有点多(其实简化下图就可以了)
双倍经验怎能错过2333
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 300+5 10 #define nm 100000 11 using namespace std; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 15 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 16 return x*f; 17 } 18 struct edge{ 19 int t,v; 20 edge *next,*rev; 21 }e[nm],*h[NM],*p=e; 22 void _add(int x,int y,int v){ 23 p->t=y;p->v=v;p->next=h[x];h[x]=p;p++; 24 } 25 void add(int x,int y,int v){ 26 _add(x,y,v);_add(y,x,v); 27 h[x]->rev=h[y];h[y]->rev=h[x]; 28 } 29 int n,m,s,_t,_x,_y,d[NM],v[NM]; 30 queue<int >q; 31 int bfs(){ 32 mem(d);mem(v); 33 v[0]++;d[0]++;q.push(0); 34 while(!q.empty()){ 35 int t=q.front();q.pop(); 36 link(t) 37 if((j->v)&&(!d[j->t]||d[j->t]>d[t]+1)){ 38 d[j->t]=d[t]+1; 39 if(!v[j->t])v[j->t]++,q.push(j->t); 40 } 41 } 42 return d[n]; 43 } 44 int dfs(int x,int k){ 45 int _a; 46 if(x==n)return k; 47 link(x) 48 if(j->v&&d[j->t]==d[x]+1&&(_a=dfs(j->t,min(k,j->v)))){ 49 j->v-=_a;j->rev->v+=_a;return _a; 50 } 51 return 0; 52 } 53 int main(){ 54 n=read();m=read(); 55 inc(i,1,n)read()?add(0,i,1):add(i,n+1,1); 56 inc(i,1,m){ 57 _x=read();_y=read(); 58 add(_x,_y,1); 59 } 60 n++; 61 while(bfs()) 62 if(_t=dfs(0,inf))s+=_t; 63 printf("%d\n",s); 64 return 0; 65 }