這道題如果直接費用流會超時。
題目只是讓我們判斷是否是最好的情況,我們只需要找到更好的一種情況即可,不需要求最好的。
也就是說按照最小費用流的做法,我們只需要在殘餘網路還能找到乙個負圈的即可。這是充分必要條件,如果達到最優解,就沒有負圈了。
所以我們按照題意建立圖還有殘餘網路。之後判斷圖中是否存在乙個負圈(spfa),如果存在則跳出,返回那個點。
當前那個點不一定在負圈當中,我們開始while找到在負圈當中的乙個點。從當前點開始-1+1即可。
#include
#include
#include
#define n_node 205
#define n_edge 30000
#define inf 100000000
using
namespace
std;
typedef
struct
star;
typedef
struct
node;
star e[n_edge];
intlist[n_node] ,tot;
intc[n_node];
//入隊次數
intmer[n_node];
//記錄路徑
ints_x[n_node] ,mark[n_node];
intnow[n_node][n_node];
node a[n_node] ,b[n_node];
void
add(
inta ,
intb ,
intc ,
intd)
intabss(
intx)
bool
spfa(
ints ,
intn)
} } }
return
0;
} int
main ()
memset(list ,0 ,sizeof
(list));
tot = 1;
intss = 0 ,tt = n + m + 1;
for(i = 1 ;i <= n ;i ++)
add(ss ,i ,0 ,0),add(i ,ss ,0 ,a[i].c);
for(i = 1 ;i <= m ;i ++)
add(i + n ,tt ,0 ,b[i].c - st[i]) ,add(tt ,i + n ,0 ,st[i]);
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
intx = spfa(tt ,tt);
if(!x)
printf("suboptimal\n"
);
memset(mark ,0 ,sizeof
(mark));
i = mer[x];
while
(1)//找到乙個肯定在環上的點
memset(mark ,0 ,sizeof
(mark));
for(i = mer[x] ;i + 1 ;i = mer[e[i].from])
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
if(j == m) printf(
"%d\n"
,now[i][j]);
else
printf(
"%d "
,now[i][j]);
} return
0;
}
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 費用流判負環 消環
題意 給出n棟房子位置和每棟房子裡面的人數,m個避難所位置和每個避難所可容納人數。然後給出乙個方案,判斷該方案是否最優,如果不是求出乙個更優的方案。思路 很容易想到用最小費用流求出最優時間,在與原方案花費時間對比判斷原方案是否最優。但是這種方法會超時的。放棄該思路。看看題目沒要求要最優解,而是得到乙...
poj 2175 最小費用最大流TLE
題意 一條街上有n個大樓,座標為xi,yi,bi個人在裡面工作。然後防空洞的座標為pj,qj,可以容納cj個人。從大樓i中的人到防空洞j去避難所需的時間為 abs xi pi yi qi 1。現在設計了乙個避難計畫,指定從大樓i到防空洞j避難的人數 eij。判斷如果按照原計畫進行,所有人避難所用的時...