BZOJ4514 Sdoi2016 數字配對

2022-05-27 15:27:12 字數 1812 閱讀 3646

題解

一開始看到這道題各種費用流的即視感。

首先這個配對應該可以想到構建二分圖模型。構建出二分圖後就比較容易把關係轉化為邊了。

但怎麼構建呢?這個還是比較巧妙的,因為只有 小的數能整除大的數 且商為質數 的2個數才能配對。

也就是說只有在質因子個數相差1的情況下可能配對,於是很容易很把數分成2個集合。

然後在2個集合間靠關係建邊。(具體怎麼建就不闡述了)

另外在前提是跑最大費用最大流的情況下,由於整張圖的流與當前費用最大的增廣流之間存在單調性,

即隨流變大,每次費用最大的增廣流費用變小。(這個可以感性理解一下,主要是得意識到有這個性質)

所以我們一次次跑spfa,跑到最大費用不能再小為止。

答案就是最後的可行流。

**

1 #include 2 #include 3 #include 4 #include 5 typedef long

long

ll;6

using

namespace

std;

7const ll inf=1e18;

8const

int n=405;9

const

int m=100000;10

inta[n],b[n],c[n],d[n];

11int

n,cnt,x;

12struct

mcmf

1323

void ins(int x,int y,int

z,ll c)

2431

void add(int x,int y,int

z,ll c)

3236

bool

spfa()

3767

}68 flag[u]=0;69

}70if (flow[t]) return1;

71else

return0;

72}73int

solve()

7485 ans+=flow[t]*f[t];

86 tot+=flow[t];

87for (int i=t;i!=s;i=pre_point[i])

8893}94

return

tot;95}

96}t;

97int

main()

98112 t.t=n+1

;113 t.cnt=n+1

;114

for (int i=1;i<=n;++i) scanf("

%d",&b[i]);

115for (int i=1;i<=n;++i) scanf("

%d",&c[i]);

116for (int i=1;i<=n;++i)

117if (d[i]&1) t.add(t.s,i,b[i],0

);118

else t.add(i,t.t,b[i],0

);119

for (int i=1;i<=n;++i)

120for (int j=1;j<=n;++j)

121if (a[i]%a[j]==0 && d[i]==d[j]+1

)122

126 cout

127return0;

128 }

view code

bzoj4514 Sdoi2016 數字配對

有 n 種數字,第 i 種數字是 ai 有 bi 個,權值是 ci。若兩個數字 ai aj 滿足,ai 是 aj 的倍數,且 ai aj 是乙個質數,那麼這兩個數字可以配對,並獲得 ci cj 的價值。乙個數字只能參與一次配對,可以不參與配對。在獲得的價值總和不小於 0 的前提下,求最多進行多少次配...

bzoj4514 Sdoi2016 數字配對

bzoj4514 sdoi2016 數字配對 題意 有 n 種數字,第 i 種數字是 ai 有 bi 個,權值是 ci。若兩個數字 ai aj 滿足ai 是 aj 的倍數且 ai aj 是乙個質數,那麼這兩個數字可以配對,並獲得 ci cj 的價值。乙個數字只能參與一次配對,可以不參與配對。在獲得的...

BZOJ 4514 Sdoi2016 數字配對

time limit 10 sec memory limit 128 mb submit 1606 solved 608 submit status discuss 有 n 種數字,第 i 種數字是 ai 有 bi 個,權值是 ci。若兩個數字 ai aj 滿足,ai 是 aj 的倍數,且 ai a...