P2756 魔术球问题 (网络流)
生活随笔
收集整理的這篇文章主要介紹了
P2756 魔术球问题 (网络流)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:n根柱子 把編號1,2,3....的球依次插到柱子上去
需要滿足相鄰的兩個球編號加起來為完全平方數 n < 55
題解:網絡流24(23)題里的?
但是一直不知道怎么建圖? 或者說建圖的意義
一般都要套路拆點 我的理解就是實際問題背景每個點是需要雙向邊的 但是網絡流算法要建反向邊 所以就拆點防止重邊 意義更明確
這個題的話把小球拆點就表示 一個放前面 一個放后面的情況 然后按題意建圖 跑最大流
我最開始以為一條增廣路代表一根柱子 其實不是 這里柱子的意義更抽象
模擬一下程序后發現 在依次加球的過程中 最大流跑通表示的是這個球可以直接接在當前安排方式的后面
如果跑不通 就要新開柱子了 同時跑新的最大流也能保證反悔操作
?
#include <bits/stdc++.h> using namespace std;int n, cnt, p, num, s, t, maxflow;struct node {int to, nex, val; }E[200005]; int head[4005]; int cur[4005];void addedge(int x, int y, int va) {E[++cnt].to = y; E[cnt].nex = head[x]; E[cnt].val = va; head[x] = cnt;E[++cnt].to = x; E[cnt].nex = head[y]; E[cnt].val = 0; head[y] = cnt; }int dep[4005]; int to[4005]; int inque[4005]; bool bfs() {for(int i = 0; i <= num * 2 + 2; i++) cur[i] = head[i], dep[i] = 0x3f3f3f3f, inque[i] = 0;dep[s] = 0;queue<int> que;que.push(s);inque[s] = 1;while(!que.empty()) {int u = que.front();que.pop();for(int i = head[u]; i; i = E[i].nex) {int v = E[i].to;if(E[i].val > 0 && dep[v] > dep[u] + 1) {dep[v] = dep[u] + 1;if(!inque[v]) {inque[v] = 1;que.push(v);}}}}if(dep[t] != 0x3f3f3f3f) return true;return false; }int vis; int dfs(int x, int flow) {if(x == t) {vis = 1;maxflow += flow;return flow;}int rflow = 0;int used = 0;for(int i = cur[x]; i; i = E[i].nex) {cur[x] = i;int v = E[i].to;if(E[i].val > 0 && dep[v] == dep[x] + 1) {if(rflow = dfs(v, min(flow - used, E[i].val))) {to[x / 2] = v / 2;used += rflow;E[i].val -= rflow;E[i ^ 1].val += rflow;if(used == flow) break;}}}return used; }void dinic() {maxflow = 0;while(bfs()) {vis = 1;while(vis) {vis = 0;dfs(s, 100000000);}} }int ans[60];int main() {p = num = 0;cnt = 1;scanf("%d", &n);s = 0; t = 1;while(p <= n) {num++;addedge(s, num << 1, 1);addedge(num << 1 | 1, t, 1);for(int i = sqrt(num) + 1; i * i < 2 * num; i++) {addedge((i * i - num) << 1, num << 1 | 1, 1);}dinic();if(!maxflow) {ans[++p] = num;}}printf("%d\n", num - 1);for(int i = 1; i <= n; i++) {printf("%d", ans[i]);for(int j = ans[i]; to[j]; j = to[j]) printf(" %d", to[j]);puts("");}return 0; } View Code?
轉載于:https://www.cnblogs.com/lwqq3/p/11150204.html
總結
以上是生活随笔為你收集整理的P2756 魔术球问题 (网络流)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 创建dynamics CRM clien
- 下一篇: 7.css常用属性