poj 2175 費用流判負環 消環

2021-06-25 18:23:01 字數 1462 閱讀 9152

題意:給出n棟房子位置和每棟房子裡面的人數,m個避難所位置和每個避難所可容納人數。然後給出乙個方案,判斷該方案是否最優,如果不是求出乙個更優的方案。

思路:很容易想到用最小費用流求出最優時間,在與原方案花費時間對比判斷原方案是否最優。但是這種方法會超時的。 放棄該思路。

看看題目沒要求要最優解,而是得到乙個更優的解,那麼如果在原圖中能夠找到乙個總費用為負的迴路的話,那就該解不是最優解,把該負環消去,更新流量,得到優化後的解。

具體操作:在spfa中,乙個點入隊次數大於頂點數時就可以判斷有負圈存在了,但這時剛剛入隊的這個點卻未必是負圈上的,

如資料1 3

0 0 4

1 0 6

1 1 6

1 2 6

0 2 2

我們用spfa找到了其中乙個負環:花費:-4 -> 2 -> 0 -> 0 -> -4,最後乙個入棧的點是3,不在該負環中

但我們可以記錄下來每個點被更新的前乙個點,沿這個路徑不停地回溯去找,直到發現找到的這個點在之間已經遇到過了,那麼找到的這個點就一定是某個負圈上的點了。最後以這個點為基礎,回溯找到整個負圈並更新流量即可。

如負環,1->2->3->4->5->6->7

6              4

1       ---> 2  --->            3        --->         7

最後點7進入spfa,被更新了n次,但7不一定是環上的點 ;

#include#include#include#include#include#includeusing namespace std;

#define maxn 5000

#define maxm 1000000

#define inf 0xffffff

struct edge

;edge e[maxm];

bool in[maxn];

int head[maxn],dis[maxn],pre[maxn],counts[maxn],en;

int vn,st,ed,n,m;

int ax[maxn],ay[maxn],az[maxn],bx[maxn],by[maxn],bz[maxn],bs[maxn];

int cost[maxn][maxn];

void add(int a,int b,int c,int cc,int d)

int distances(int x1,int y1,int x2,int y2)

int spfa(int s)

dis[s]=0,in[s]=true,q.push(s);

counts[s]=1;

while(!q.empty())

}} }

return -1;

}void update(int p)

{ int flow=inf;

int i,u=pre[p];

i=u;

if(e[u].c

poj 2175 費用流 消圈

這道題如果直接費用流會超時。題目只是讓我們判斷是否是最好的情況,我們只需要找到更好的一種情況即可,不需要求最好的。也就是說按照最小費用流的做法,我們只需要在殘餘網路還能找到乙個負圈的即可。這是充分必要條件,如果達到最優解,就沒有負圈了。所以我們按照題意建立圖還有殘餘網路。之後判斷圖中是否存在乙個負圈...

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...

poj 2175 最小費用最大流TLE

題意 一條街上有n個大樓,座標為xi,yi,bi個人在裡面工作。然後防空洞的座標為pj,qj,可以容納cj個人。從大樓i中的人到防空洞j去避難所需的時間為 abs xi pi yi qi 1。現在設計了乙個避難計畫,指定從大樓i到防空洞j避難的人數 eij。判斷如果按照原計畫進行,所有人避難所用的時...