求最大密度子图
记得在最后一次寻找的时候记得将进入的边放大那么一点点,这样有利于当每条边都满流的情况下会选择点
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <vector> #include <queue> #include <cmath> using namespace std; const int maxn=105; const double eps=0.00000001; const double INF=10005*10005; vector<int>ans; struct Dinic { struct Edge { int from,to; double cap,flow; Edge(int cfrom=0,int cto=0,double ccap=0,double cflow=0) { from=cfrom; to=cto; cap=ccap; flow=cflow; } }; int n,m,s,t; vector<Edge>edges; vector<int>G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void init(int n) { this->n=n; m=0; edges.clear(); for(int i=0; i<=n; i++)G[i].clear(); } void AddEdge(int from,int to,double cap) { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m+=2; G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis,false,sizeof(vis)); queue<int>Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge &e =edges[G[x][i]]; if(vis[e.to]==false&&e.cap>e.flow) { vis[e.to]=1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } double DFS(int x, double a) { if(x==t||a==0)return a; double flow=0,f; for(int &i=cur[x]; i<G[x].size(); i++) { Edge &e=edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } double Maxflow(int s,int t) { this->s=s; this->t=t; double flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); } return flow; } void finde(int x) { vis[x]=1; ans.push_back(x); for(int i=0;i<G[x].size(); i++) { Edge &e=edges[G[x][i]]; if(vis[e.to]||e.cap<=e.flow)continue; finde(e.to); } } void solve() { memset(vis,false,sizeof(vis)); vis[s]=1; vis[t]=1; for(int i=0; i<G[s].size(); i++) { Edge &e=edges[G[s][i]]; if(vis[e.to]||e.cap<=e.flow)continue; finde(e.to); } } }T; int d[maxn]; int A[1005],B[1005]; double U; void build(int n,int m,double g,int op=0) { T.init(n+2); for(int i=1; i<=n; i++) { T.AddEdge(n+1,i,U+op*eps*2); T.AddEdge(i,n+2,U+g*2-d[i]); } for(int i=1; i<=m; i++) { T.AddEdge(A[i],B[i],1); T.AddEdge(B[i],A[i],1); } } int main() { int n,m; while(scanf("%d%d",&n,&m)==2) { if(m==0) { printf("1 1 ");continue; } memset(d,0,sizeof(d)); for(int i=1; i<=m; i++) { scanf("%d%d",&A[i],&B[i]); d[A[i]]++;d[B[i]]++; } U=m; double cL=0.0,cR=1.0*m; for(int i=0; i<100; i++) { double mid=(cL+cR)/2; build(n,m,mid); double ans=T.Maxflow(n+1,n+2); ans=(U*n-ans)/2; if(ans>0) cL=mid; else cR=mid; } build(n,m,cL,1); T.Maxflow(n+1,n+2); ans.clear(); T.solve(); sort(ans.begin(),ans.end()); int ge=unique(ans.begin(),ans.end())-ans.begin(); printf("%d ",ge); for(int i=0; i<ge;i++) printf("%d ",ans[i]); } return 0; }