[二分图 费用流] BZOJ 4514 [Sdoi2016]数字配对

来源:互联网 发布:马牌cc5与cc6数据对比 编辑:程序博客网 时间:2024/05/22 20:10

不会有奇环,那么就建二分图

然后跑最大费用流,直到费用小于零为止,处理下零头


#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define cl(x) memset(x,0,sizeof(x))#define oo 1LL<<60#define V G[p].vusing namespace std;typedef long long ll;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=205;struct edge{int u,v,f; ll w;int next;};edge G[N*N*10];int head[N],inum=1;inline void add(int u,int v,ll w,int f,int p){G[p].u=u; G[p].v=v; G[p].w=w; G[p].f=f; G[p].next=head[u]; head[u]=p;}inline void link(int u,int v,ll w,int f){add(u,v,w,f,++inum); add(v,u,-w,0,++inum);}int S,T;const int ND=1000000;int Q[ND],l,r;int ins[N],pre[N];ll dis[N];ll Mincost,last,Flow; inline bool SPFA(){l=r=-1; cl(ins); cl(Q); cl(pre); for (int i=1;i<=T;i++) dis[i]=-oo;Q[(++r)%ND]=S; ins[S]=1; dis[S]=0;while (l!=r){int u=Q[(++l)%ND]; ins[u]=0;for (int p=head[u];p;p=G[p].next)if (G[p].f && dis[V]<dis[u]+G[p].w){dis[V]=dis[u]+G[p].w; pre[V]=p;if (!ins[V])Q[(++r)%ND]=V,ins[V]=1;}}if (dis[T]==-oo) return 0;ll flow=1<<30,cost=dis[T];for (int p=pre[T];p;p=pre[G[p].u]) flow=min(flow,(ll)G[p].f);last=Mincost;Mincost+=flow*cost;if (Mincost<0){Flow+=last/-cost;printf("%lld\n",Flow);exit(0);}Flow+=flow;for (int p=pre[T];p;p=pre[G[p].u])G[p].f-=flow,G[p^1].f+=flow;return 1;}int n;int a[N],b[N],c[N];const int maxn=100000;int prime[maxn+5],vst[maxn+5],pnum;inline void Pre(){for (int i=2;i<=maxn;i++)if (!vst[i]){prime[++pnum]=i;for (int j=i+i;j<=maxn;j+=i) vst[j]=1;}}inline bool Jud(int x){if (x==1) return 0;for (int i=1;i<=pnum && (ll)prime[i]*prime[i]<=x;i++)if (x%prime[i]==0)return 0;return 1;}int tag[N][N];int clr[N];void dfs(int u,int c){clr[u]=c;for (int i=1;i<=n;i++)if (i!=u && clr[i]==-1 && tag[i][u])dfs(i,c^1);}int main(){freopen("t.in","r",stdin);freopen("t.out","w",stdout);Pre();read(n);for (int i=1;i<=n;i++) read(a[i]);for (int i=1;i<=n;i++) read(b[i]);for (int i=1;i<=n;i++) read(c[i]);for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if ((a[i]%a[j]==0 && Jud(a[i]/a[j])) || (a[j]%a[i]==0 && Jud(a[j]/a[i])))tag[i][j]=1;memset(clr,-1,sizeof(clr));for (int i=1;i<=n;i++)if (clr[i]==-1)dfs(i,0);S=n+1; T=n+2;for (int i=1;i<=n;i++)if (!clr[i])link(S,i,0,b[i]);elselink(i,T,0,b[i]);for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if (!clr[i] && clr[j] && tag[i][j])link(i,j,(ll)c[i]*c[j],1<<30);while (SPFA());printf("%lld\n",Flow);return 0;}


0 0
原创粉丝点击