就是裸题啦。
注意最后还要跑一遍网络流才是正确的图。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> #define maxv 105 #define maxn 1005 #define maxe 1000050 #define inf 1000000007 #define eps 1e-5 using namespace std; int n,m,x[maxn],y[maxn],nume=1,g[maxv],dis[maxv],ans=0,s,t,d[maxv]; bool vis[maxv]; struct edge { int v,nxt; double f; }e[maxe]; queue <int> q; bool comp(double x,double y) { if (fabs(x-y)<=eps) return 0; else if (x<y) return -1; else return 1; } void addedge(int u,int v,double f) { e[++nume].v=v;e[nume].nxt=g[u]; e[nume].f=f;g[u]=nume; e[++nume].v=u;e[nume].nxt=g[v]; e[nume].f=0;g[v]=nume; } void build(double g) { nume=1; for (int i=1;i<=n;i++) addedge(s,i,(double)m),addedge(i,t,(double)m+2*g-d[i]); for (int i=1;i<=m;i++) addedge(x[i],y[i],1),addedge(y[i],x[i],1); } bool bfs() { for (int i=s;i<=t;i++) dis[i]=inf; dis[s]=0;q.push(s); 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 ((comp(e[i].f,0)>0) && (dis[v]>dis[head]+1)) { dis[v]=dis[head]+1; q.push(v); } } } return dis[t]!=inf; } double dinic(int x,double low) { double ret=0; if (x==t) return low; for (int i=g[x];i && (comp(low,0)>0);i=e[i].nxt) { int v=e[i].v; if ((comp(e[i].f,0)>0) && (dis[v]==dis[x]+1)) { double dd=dinic(v,min(e[i].f,low)); ret+=dd;low-=dd; e[i].f-=dd;e[i^1].f+=dd; } } if (comp(ret,0)<=0) dis[x]=inf; return ret; } double check(double g) { build(g);double max_flow=0; while (bfs()) max_flow+=dinic(s,inf); return (double)m*n-max_flow; } void binary_search() { double l=0,r=m,min_gap=(double)1/n/n,mid; while (r-l>min_gap) { memset(g,0,sizeof(g)); mid=(l+r)/2; double cs=check(mid); if (comp(cs,0)>0) l=mid;else r=mid; } memset(g,0,sizeof(g));double cs=check(l);cs=0; return; } void find(int x) { ans++;vis[x]=true; for (int i=g[x];i;i=e[i].nxt) { if ((comp(e[i].f,0)>0) && (!vis[e[i].v])) find(e[i].v); } } int main() { scanf("%d%d",&n,&m);s=0;t=n+1; if (!m) {printf("1\n");return 0;} for (int i=1;i<=m;i++) { scanf("%d%d",&x[i],&y[i]); d[x[i]]++;d[y[i]]++; } binary_search(); find(s); printf("%d\n",ans-1); return 0; }