題意:
一條街上有n個大樓,座標為xi,yi,bi個人在裡面工作。
然後防空洞的座標為pj,qj,可以容納cj個人。
從大樓i中的人到防空洞j去避難所需的時間為 abs(xi - pi) + (yi - qi) + 1。
現在設計了乙個避難計畫,指定從大樓i到防空洞j避難的人數 eij。
判斷如果按照原計畫進行,所有人避難所用的時間總和是不是最小的。
若是,輸出「opetimal",若否,輸出」suboptimal"然後輸出一組時間總和更小的避難方案。
解析:在代表大樓的頂點集合u和代表放空洞的頂點集合v之外,新增源點s和匯點t。
s向各個大樓u連一條容量為樓內人數,費用為0的邊;
從防空洞v向t連一條容量為防空洞的人數,費用為0的邊;
大樓與防空洞連一條容量為inf,費用為它們之間距離的邊。
求最小費用最大流。
......
然後就超時了- -。
超時**:
#include #include #include #include #include #include #include #include #include #include #include #include #define ll long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1
using namespace std;
const int maxn = 200 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double ee = exp(1.0);
struct edge
edge(int _fr, int _to, int _cap, int _flow, int _cost)
};vectoredges;
vectorg[maxn];
bool inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
int v;
void init(int v)
void addedge(int fr, int to, int cap, int cost)
bool bellmanford(int s, int t, int& flow, int& cost)
memset(inq, false, sizeof(inq));
d[s] = 0;
inq[s] = true;
p[s] = 0;
a[s] = inf;
queueq;
q.push(s);
while (!q.empty())}}
}if (d[t] == inf)
return false;
flow += a[t];
cost += d[t] * a[t];
int u = t;
while (u != s)
return true;
}int mcmf(int s, int t)
int n, m;
int x[maxn], y[maxn], b[maxn];
int p[maxn], q[maxn], c[maxn];
int e[maxn][maxn];
int main()
for (int i = 0; i < m; i++)
for (int i = 0; i < n; i++)
}int s = n + m, t = s + 1;
init(t + 1);
int costnow = 0;
int peoplenum = 0;
//0 ~ n - 1 -----大樓
//n ~ n + m - 1 -----防空洞
for (int i = 0; i < n; i++)
}for (int i = 0; i < n; i++)
for (int i = 0; i < m; i++)
if (mcmf(s, t) < costnow)}}
else
}return 0;
}
然後這個題目求的不是最小花費。。。
只要判斷是不是最小就行了。
所以更高效的求法是:某個流f是同流量中的最小費用流,等價於f的殘餘網路中沒有負圈。
因此,在指派問題對應的圖中,增廣所給避難計畫所對應的流,然後再殘餘網路上檢查有沒有負圈,用floyd判斷。
如果找到負圈,就沿著負圈增廣。
POJ2175 最小費用流消圈演算法
include include include include include using namespace std const int nn 210 const int mm 100000 const int inf 0x3fffffff inline int abs int x int n,m...
最小費用最大流
網 絡流的基本問題為 設乙個有向賦權圖g v,e v 其中有兩個特殊的節點s和s s稱為發點,s 稱為收點。圖中各 邊的方向和權數表示允許的流向和最大可能的流量 容量 問在這個網路圖中從發點流出到收點匯集,最大可通過的實際流量為多少?流向的分布情況為怎樣?設有乙個網路圖g v,e v e中的每條邊 ...
最小費用最大流
const int maxn 250 const int maxm 62272 const int inf 0x4ffffff int n,m struct edge edge maxm int head maxn cnt void init void addedge int u,int v,int...