标签:
最大流。。建图方式都是玄学啊。。
//Dinic是O(n2m)的。 #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-‘0‘,c=getchar(); return x; } const int nmax=305; const int maxn=200000; const int inf=0x7f7f7f7f; struct edge{ int to,cap;edge *next,*rev; }; edge es[maxn],*pt=es,*head[nmax]; void add(int u,int v,int d){ pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->cap=0;pt->next=head[v];head[v]=pt++; head[u]->rev=head[v];head[v]->rev=head[u]; } edge *cur[nmax],*p[nmax]; int cnt[nmax],h[nmax]; int maxflow(int s,int t,int n){ clr(cnt,0);cnt[0]=n;clr(h,0); int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break; if(e){ a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a;a=inf; } }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow; } int main(){ int n=read(),m=read(),u,v,s=0,t=n+1; rep(i,1,n) { u=read(); (!u)?add(i,t,1):add(s,i,1); } rep(i,1,m) u=read(),v=read(),add(u,v,1),add(v,u,1); printf("%d\n",maxflow(s,t,t+1)); return 0; }
在第一个例子中,所有小朋友都投赞成票就能得到最优解
bzoj1934: [Shoi2007]Vote 善意的投票
标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5858165.html