一个最小割模型吧。。。。1连源,0连汇,朋友之间互相连,最小割等于最大流。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxv 650 #define maxe 200500 #define inf 1000000007 using namespace std; struct edge { int v,f,nxt; }e[maxe]; int n,m,s,t,g[maxv],x,y,nume=1,dis[maxv]; bool vis[maxv]; queue <int> q; void addedge(int u,int v,int f) { e[++nume].v=v; e[nume].f=f; e[nume].nxt=g[u]; g[u]=nume; e[++nume].v=u; e[nume].f=0; e[nume].nxt=g[v]; g[v]=nume; } bool bfs() { while (!q.empty()) q.pop(); memset(vis,false,sizeof(vis)); memset(dis,-1,sizeof(dis)); q.push(s);vis[s]=true;dis[s]=0; while (!q.empty()) { int head=q.front();q.pop(); for (int i=g[head];i;i=e[i].nxt) { int v=e[i].v; if ((vis[v]==false) && (e[i].f)) { dis[v]=dis[head]+1; vis[v]=true; q.push(v); } } } if (dis[t]==-1) return false; return true; } int dinic(int x,int low) { if (x==t) return low; else { int ret=0; for (int i=g[x];low && i;i=e[i].nxt) { int v=e[i].v; if ((e[i].f) && (dis[v]==dis[x]+1)) { int dd=dinic(v,min(low,e[i].f)); ret=ret+dd;low=low-dd; e[i].f=e[i].f-dd;e[i^1].f=e[i^1].f+dd; } } if (ret==0) dis[x]=-1; return ret; } } int main() { scanf("%d%d",&n,&m); s=0;t=2*n+1; for (int i=1;i<=n;i++) { scanf("%d",&x); if (x==1) addedge(s,i,1); else addedge(i+n,t,1); } for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); addedge(x,y+n,1); addedge(y,x+n,1); } int min_cut=0; while (bfs()) min_cut+=dinic(s,inf); printf("%d\n",min_cut); return 0; }