[BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[Problem Description] 皮卡丘被火箭隊用邪惡的計謀搶走了!這三個壞家伙還給小智留下了赤果果的挑釁!為了皮卡丘,也為了正義,小智和他的朋友們義不容辭的踏上了營救皮卡丘的道路。 火箭隊一共同擁有N個據點,據點之間存在M條雙向道路。據點分別從1到N標號。小智一行K人從真新鎮出發,營救被困在N號據點的皮卡丘。為了方便起見,我們將真新鎮視為0號據點,一開始K個人都在0號點。 因為火箭隊的重重布防,要想摧毀K號據點,必須依照順序先摧毀1到K-1號據點,而且,假設K-1號據點沒有被摧毀,因為防御的連鎖性,小智一行不論什么一個人進入據點K,都會被發現,并產生嚴重后果。因此,在K-1號據點被摧毀之前,不論什么人是不可以經過K號據點的。 為了簡化問題,我們忽略戰斗環節,小智一行不論什么一個人經過K號據點即覺得K號據點被摧毀。被摧毀的據點依舊是能夠被經過的。 K個人是能夠分頭行動的,僅僅要有不論什么一個人在K-1號據點被摧毀之后,經過K號據點,K號據點就被摧毀了。顯然的,僅僅要N號據點被摧毀,皮卡丘就得救了。 野外的道路是不安全的,因此小智一行希望在摧毀N號據點救出皮卡丘的同一時候,使得K個人所經過的道路的長度總和最少。 請你幫助小智設計一個最佳的營救方案吧! [Algorithm] 最小費用最大流 [Analysis] 題目有幾個關鍵點: 1.每個點都必須有人經過 2.經過j點時,0~j-1必須都經過了才干夠 由此能夠構造出一個網絡流的模型。 因為每一個節點的第一次訪問,必然是由小于它的節點完畢的,所以先用floyd預處理dis[k][i][j]表示i到j僅僅經過小于等于k的點的最短路。建圖例如以下 1.S->0 cap=k cost=0 2.i->T cap=1 cost=0 3.S->i+n cap=1 cost=0 4.i+n->j cap=INF cost=dis[j][i][j] 1是用來限制人數的,2則保證每一個點經過一次,因為第一次經過該點時流向了T消耗了流量,所以每一個點給予補充流量,即建圖3。4則是從一個剛剛第一次經過的點繼續訪問其他點。這樣建圖能夠發現,每一個點的第一次訪問都被轉化成了一條從S出發的流且沒有交叉,這樣能夠隨意調整訪問順序,保證了j訪問之前0~j-1都已經訪問過 [Pay Attention] 因為floyd要用鄰接矩陣,注意推斷重邊的情況取最小。 還有要從這樣的點至少經過一次的建模中吸取經驗 [Code] /**************************************************************Problem: 2324User: gaotianyu1350Language: C++Result: AcceptedTime:392 msMemory:7620 kb
****************************************************************/#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <iostream>
using namespace std;#define MAXN 350
#define MAXM 300000
#define INF 0x3f3f3f3fint point[MAXN], next[MAXM], v[MAXM], flow[MAXM], cap[MAXM], w[MAXM];
int lastedge[MAXN], dis[MAXN];
bool check[MAXN];
int tot = -1;int n, m, people;
int map[MAXN][MAXN];inline void init()
{memset(map, 0x7f, sizeof(map));memset(point, -1, sizeof(point));memset(next, -1, sizeof(next));tot = -1;
}inline void addedge(int x, int y, int theCap, int theDis)
{tot++;next[tot] = point[x]; point[x] = tot; v[tot] = y; flow[tot] = 0; cap[tot] = theCap; w[tot] = theDis;tot++;next[tot] = point[y]; point[y] = tot;v[tot] = x; flow[tot] = 0; cap[tot] = 0; w[tot] = - theDis;
}inline int addflow(int s, int t)
{int now = t;int ans = INF;while (now != s){int temp = lastedge[now];ans = min(ans, cap[temp] - flow[temp]);now = v[lastedge[now] ^ 1];}now = t;while (now != s){flow[lastedge[now]] += ans;flow[lastedge[now] ^ 1] -= ans;now = v[lastedge[now] ^ 1];}return ans;
}bool spfa(int s, int t, int &maxflow, int &mincost)
{queue<int> q;while (!q.empty()) q.pop();memset(dis, 0x7f, sizeof(dis));memset(check, 0, sizeof(check));dis[s] = 0; check[s] = true; q.push(s);while (!q.empty()){int now = q.front(); q.pop();check[now] = false;for (int temp = point[now]; temp != -1; temp = next[temp])if (flow[temp] < cap[temp] && dis[now] + w[temp] < dis[v[temp]]){dis[v[temp]] = dis[now] + w[temp];lastedge[v[temp]] = temp;if (!check[v[temp]])check[v[temp]] = true, q.push(v[temp]);}}if (dis[t] > INF) return false;int add = addflow(s, t);maxflow += add;mincost += add * dis[t];return true;
}inline int solve(int s, int t)
{int maxflow = 0, mincost = 0;while (spfa(s, t, maxflow, mincost));/*{int tiaoshi = 1;tiaoshi++;}*///printf("mflow :%d\n", maxflow);return mincost;
}inline void build(int start, int end)
{addedge(start, 0, people, 0);for (int i = 1; i <= n; i++){addedge(i, end, 1, 0);addedge(start, i + n, 1, 0);//addedge(i, i + n, INF, 0);}for (int k = 0; k <= n; k++)for (int i = 0; i <= n; i++)for (int j = 0; j <= n; j++)if (i != j){if (map[i][k] < INF && map[k][j] < INF)map[i][j] = min(map[i][j], map[i][k] + map[k][j]);if (k == j && i < j && map[i][j] < INF)addedge(i == 0 ? 0 : i + n, j, INF, map[i][j]); }
}int main()
{//freopen("input.txt", "r", stdin);init();scanf("%d%d%d", &n, &m, &people);for (int i = 1; i <= m; i++){int x, y, z;scanf("%d%d%d", &x, &y, &z);if (z < map[x][y])map[x][y] = map[y][x] = z;}build(2 * n + 1, 2 * n + 2);printf("%d\n", solve(2 * n + 1, 2 * n + 2));
}
轉載于:https://www.cnblogs.com/mengfanrong/p/3845444.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的[BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cocos2dx引用计数
- 下一篇: 数据库索引以及优化