日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)

發(fā)布時(shí)間:2023/12/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

P2765 魔術(shù)球問題

題目描述

?問題描述:

假設(shè)有n根柱子,現(xiàn)要按下述規(guī)則在這n根柱子中依次放入編號為1,2,3,...的球。

(1)每次只能在某根柱子的最上面放球。

(2)在同一根柱子中,任何2個(gè)相鄰球的編號之和為完全平方數(shù)。

試設(shè)計(jì)一個(gè)算法,計(jì)算出在n根柱子上最多能放多少個(gè)球。例如,在4 根柱子上最多可放11 個(gè)球。

?編程任務(wù):

對于給定的n,計(jì)算在n根柱子上最多能放多少個(gè)球。

輸入格式

第1 行有1個(gè)正整數(shù)n,表示柱子數(shù)。

輸出格式

程序運(yùn)行結(jié)束時(shí),將n 根柱子上最多能放的球數(shù)以及相應(yīng)的放置方案輸出。文件的第一行是球數(shù)。接下來的n行,每行是一根柱子上的球的編號。

輸入輸出樣例

輸入 #1復(fù)制

4

輸出 #1復(fù)制

11 1 8 2 7 9 3 6 10 4 5 11

說明/提示

4<=n<=55

思路:

首先知道放球的個(gè)數(shù)和柱子的個(gè)數(shù)是成正相關(guān)的,

一直增加球,對于每一個(gè)球i,將比其小的,能和其相加為平方數(shù)的,統(tǒng)一連中間邊。

之所以叫中間邊,是因?yàn)檫@題要拆點(diǎn),設(shè)源點(diǎn)和匯點(diǎn)分別為S和T。

將每一個(gè)點(diǎn)i,拆為 Xi,Yi,

每一個(gè)點(diǎn)將其S與Xi連接,Yi與T連接,

中間點(diǎn)就是如果i節(jié)點(diǎn)和j節(jié)點(diǎn)相連接,

就Xi 與Yj,相連,。以上講到的邊,流量全為1.

當(dāng)num個(gè)數(shù)建立的容量網(wǎng)絡(luò)的最小邊覆蓋x>n時(shí),即n個(gè)柱子無法覆蓋掉num個(gè)數(shù)時(shí),

結(jié)束加邊操作,此時(shí)num-1,就是N個(gè)柱子能覆蓋到的最大數(shù)字。

在dinic算法中增光路的過程中,記錄每一個(gè)v,增廣的下一個(gè)節(jié)節(jié)點(diǎn)u。

一路鏈狀輸出就是方法。

代碼:

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define sz(a) int(a.size()) #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c)) #define du2(a,b) scanf("%d %d",&(a),&(b)) #define du1(a) scanf("%d",&(a)); using namespace std; typedef long long ll; ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;} ll lcm(ll a, ll b) {return a / gcd(a, b) * b;} ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;} void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}} void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}inline void getInt(int* p); const int maxn = 1000010; const int inf = 0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ const int INF = (1 << 30); const int MAXN = 400000; int idx = 0, e[MAXN], f[MAXN], ne[MAXN], h[100000]; void add(int a, int b, int c) {e[idx] = b, ne[idx] = h[a], f[idx] = c, h[a] = idx++;e[idx] = a, ne[idx] = h[b], f[idx] = 0, h[b] = idx++; } int S, T, ch[MAXN], q[MAXN], nex[MAXN]; bool tell() {memset(ch, -1, sizeof(ch));int head = 0, tail = 0;ch[q[0] = S] = 0;while (head <= tail) {int t = q[head++];for (int i = h[t]; i != -1; i = ne[i]) {if (ch[e[i]] == -1 && f[i]) {ch[q[++tail] = e[i]] = ch[t] + 1;}}}return ch[T] != -1; } int zeng(int a, int b) {if (a == T)return b;int r = 0;for (int i = h[a]; i != -1; i = ne[i]) {if (ch[a] + 1 == ch[e[i]] && f[i]) {int t = zeng(e[i], min(b - r, f[i]));if (t > 0){// 可找路徑。nex[a >> 1] = (e[i] >> 1);}f[i] -= t; r += t; f[i ^ 1] += t;}}if (!r)ch[a] = -1;return r; } int dinic() {int r = 0, t = 0;while (tell()) {while (t = zeng(S, INF)) {r += t;}}return r; } void set_S_T(int s, int t) {S = s;T = t; } void init() {memset(h, -1, sizeof(h));memset(nex, -1, sizeof(nex)); } int n; int w[1000]; bool vis[maxn]; int main() {//freopen("D:\\code\\text\\input.txt","r",stdin);//freopen("D:\\code\\text\\output.txt","w",stdout);gbtb;init();S = 0;T = 1e4 + 10;cin >> n;int now = 0;int num = 0;while (now <= n){++num;add(S, num << 1, 1);add((num << 1) | 1, T, 1);for (int i = sqrt(num) + 1; i * i < (num << 1); ++i){add((i * i - num) << 1, (num << 1) | 1, 1);}int s = dinic();if (!s){w[++now] = num;}}cout << num - 1 << endl;int k;repd(i, 1, n){if (!vis[w[i]]){k = w[i];cout << k;vis[k] = 1;while (nex[k] != -1 && nex[k] != (T) >> 1 ){k=nex[k];vis[k]=1;cout<<" "<<k;}cout<<endl;}}return 0; }inline void getInt(int* p) {char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}}else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}} }

轉(zhuǎn)載于:https://www.cnblogs.com/qieqiemin/p/11632802.html

總結(jié)

以上是生活随笔為你收集整理的洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。