费用流里spfa最后的判断要写成dis[t]>=0而不是dis[t]!=-inf否则会WAWAWA……
#include #include #include #include using namespace std;const int N=200005,inf=1e9;int n,tot,s,t,ans,dis[N],h[N],cnt=1,p[N],fr[N];bool v[N];struct qwe{ int ne,no,to,va,c;}e[N*10];void add(int u,int v,int w,int c){ cnt++; e[cnt].ne=h[u]; e[cnt].no=u; e[cnt].to=v; e[cnt].va=w; e[cnt].c=c; h[u]=cnt;}void ins(int u,int v,int w,int c){ add(u,v,w,c); add(v,u,0,-c);}bool spfa(){ for(int i=s;i<=t;i++) dis[i]=-inf; memset(v,0,sizeof(v)); queue q; dis[s]=0; v[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); v[u]=0; for(int i=h[u];i;i=e[i].ne) if(e[i].va&&dis[u]+e[i].c>dis[e[i].to]) { dis[e[i].to]=dis[u]+e[i].c; fr[e[i].to]=i; if(!v[e[i].to]) { v[e[i].to]=1; q.push(e[i].to); } } } return dis[t]>=0;}void mcf(){ int x=inf; for(int i=fr[t];i;i=fr[e[i].no]) x=min(x,e[i].va); for(int i=fr[t];i;i=fr[e[i].no]) { e[i].va-=x; e[i^1].va+=x; ans+=x*e[i].c; }}int clc(int n,int x){ long long t=x; while(t*x<=n) t*=x; return t;}int main(){ scanf("%d",&n); for(int i=2;i<=n;i++) { if(!v[i]) p[++tot]=i; for(int j=1;j<=tot&&p[j]*i<=n;j++) { v[i*p[j]]=1; if(i%p[j]==0) break; } } s=0,t=tot+1; int pos=0; for(int i=1;i<=tot;i++) { if(p[i]>=n/2) { ans+=p[i]; continue; } if((long long)p[i]*p[i]<=n) { ins(s,i,1,0); ans+=clc(n,p[i]); } else { if(!pos) pos=i; ins(i,t,1,0); ans+=p[i]; } } for(int i=1;i n) break; int nw=clc(n/p[j],p[i])*p[j]-clc(n,p[i])-p[j]; if(nw>0) ins(i,j,1,nw); } while(spfa()) mcf(); printf("%d\n",ans+1); return 0;}