bzoj 4514: 数字配对
题目大意
题解
我们打表观察规律发现一定能构成一张二分图
也就是不存在奇环
所以我们一般保证费用非负的最大流即可.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 256;
const int inf = 0x3f3f3f3f;
inline bool judge(int n){
if(n == 1) return false;
if(n == 2) return true;
for(int i = 2;i*i<=n;++i){
if(n % i == 0) return false;
}return true;
}
int a[maxn],b[maxn];ll c[maxn];
namespace gra{
struct Edge{
int to,next;
}G[21010];
int head[maxn],cnt;
void add(int u,int v){
//printf("%d\n",cnt);
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
inline void insert(int u,int v){
add(u,v);add(v,u);
}
int col[maxn];
#define v G[i].to
void dfs(int u,int c){
col[u] = c;
for(int i = head[u];i;i=G[i].next){
if(col[v] == -1) dfs(v,c^1);
}
}
#undef v
}
namespace net{
struct Edge{
int to,next,cap;
ll cost;
}G[21010];
int head[maxn],cnt=1;
void add(int u,int v,int c,ll co){
//printf("%d\n",cnt);
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
G[cnt].cap = c;
G[cnt].cost = co;
}
inline void insert(int u,int v,int c,ll co){
//printf("%d -> %d (%d,%lld)\n",u,v,c,co);
add(u,v,c,co);add(v,u,0,-co);
}
const int lim = maxn<<2;
int S = maxn-5,T = S+1,l,r,q[lim+10];
int flow[maxn],p[maxn];
ll dis[maxn],nw_dis;
int ans;
bool inq[maxn];
inline int find(int r,ll w){
int l = 0,ret = 0;
while(l <= r){
int mid = l+r >> 1;
if(mid*w+nw_dis >= 0) ret = mid,l = mid+1;
else r = mid-1;
}return ret;
}
#define v G[i].to
bool spfa(){
memset(dis,-0x3f,sizeof dis);
l = 0;r = -1;q[++r] = S;
dis[S] = 0;flow[S] = inf;
inq[S] = true;
while(l <= r){
int u = q[l % lim];++l;
for(int i = head[u];i;i=G[i].next){
if(dis[v] < dis[u] + G[i].cost && G[i].cap){
dis[v] = dis[u] + G[i].cost;
flow[v] = min(flow[u],G[i].cap);
p[v] = i;
if(!inq[v]){
q[++r % lim] = v;
inq[v] = true;
}
}
}inq[u] = false;
}if(dis[T] == dis[0]) return false;
if(dis[T] < 0) flow[T] = find(flow[T],dis[T]);
if(flow[T] == 0) return false;
ans += flow[T];
nw_dis += flow[T]*dis[T];
for(int u = T;u != S;u = G[p[u]^1].to)
G[p[u]].cap -= flow[T],G[p[u]^1].cap += flow[T];
return true;
}
#undef v
}
int main(){
int n;read(n);memset(gra::col,-1,sizeof gra::col);
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(i == j) continue;
if(a[i] % a[j] == 0 && judge(a[i]/a[j])){
gra::insert(i,j);
}
}
}
for(int i=1;i<=n;++i) if(gra::col[i] == -1) gra::dfs(i,0);
for(int u=1;u<=n;++u){
if(gra::col[u] == 0){
net::insert(net::S,u,b[u],0);
for(int i = gra::head[u];i;i=gra::G[i].next){
net::insert(u,gra::G[i].to,inf,c[u]*c[gra::G[i].to]);
}
}else{
net::insert(u,net::T,b[u],0);
}
}while(net::spfa());
printf("%d\n",net::ans);
getchar();getchar();
return 0;
}
人就像命运下的蝼蚁,谁也无法操控自己的人生.