最小割。。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 }
View Code

 

posted on 2015-12-24 20:34  onlyRP  阅读(119)  评论(0编辑  收藏  举报