題意:給出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。判斷如果按照原計畫進行,所有人避難所用的時...