BZOJ3232 圈地遊戲

2022-04-28 20:36:08 字數 1593 閱讀 3493

bzoj

dzy家的後院有一塊地,由n行m列的方格組成,格仔內種的菜有一定的價值,並且每一條單位長度的格線有一定的費用。

dzy喜歡在地里散步。他總是從任意乙個格點出發,沿著格線行走直到回到出發點,且在行走途中不允許與已走過的路線有任何相交或觸碰(出發點除外)。記這條封閉路線內部的格仔總價值為v,路線上的費用總和為c,dzy想知道v/c的最大值是多少。

第一行為兩個正整數n,m。

接下來n行,每行m個非負整數,表示對應格仔的價值。

接下來n+1行,每行m個正整數,表示所有橫向的格線上的費用。

接下來n行,每行m+1個正整數,表示所有縱向的格線上的費用。

(所有資料均按從左到右,從上到下的順序輸入,參見樣例和配圖)

輸出一行僅含乙個數,表示最大的v/c,保留3位小數。

3 4

1 3 3 3

1 3 1 1

3 3 1 0

100 1 1 1

97 96 1 1

1 93 92 92

1 1 90 90

98 1 99 99 1

95 1 1 1 94

1 91 1 1 89

1.286
肯定是先分數規劃一波啦。

這樣一來選出的點產生正權,選出的邊產生負權,可以跑乙個最大權閉合子圖判斷是否存在一種選法使權值和大於零。

具體的建圖:

1、源點\(s\)向每個點連點權的邊,表示若不選這個點需要付出點權的代價。

2、相鄰點之間連\(mid*\)邊權的雙向邊,表示若兩個點的選取狀態不同,則它們中間的那條邊就一定被經過了,需要付出\(mid*\)邊權的代價。

3、邊界上的點向匯點\(t\)連\(mid*\)邊權的邊,表示這個點若要選就需要走過邊界上的這條邊。

#include#include#include#includeusing namespace std;

int gi()

#define p(i,j) ((i-1)*m+j)

const int n = 55;

const double eps = 1e-5;

struct edgea[n*n*n];

int n,m,s,t,head[n*n],cnt=1,dep[n*n],cur[n*n];

double sum,val[n][n],h[n][n],z[n][n];

queueq;

void link(int u,int v,double w);head[u]=cnt;

a[++cnt]=(edge);head[v]=cnt;

}bool bfs()

return dep[t];

}double dfs(int u,double f)

} return 0;

}double dinic()

} return res;

}bool check(double mid)

int main()

printf("%.3lf\n",l);return 0;

}

bzoj 3232 圈地遊戲

題意 在乙個n m的網格裡,邊上有花費,格里有權值 從任意乙個點開始繞一圈,繞乙個簡單環出來,裡面的所有格仔就是收益 求最大的收益 花費 所有數 100 題解 考慮01分數規劃的方式,但是花費和權值不在一起 那麼考慮將格內的權值轉化到邊上 實際上將邊有向化,按邊方向左面一行的權值為正,右面為負,加起...

BZOJ3232 圈地遊戲

膜拜下whx大爺 好神的做法 首先比值型別的最大值一般要二分答案轉判定。現在要你找到乙個環使得c mid v 0。這十分類似spfa判負環 所以我們考慮建圖找負環,每個網格線的交點向周圍四個方向建邊,邊權怎麼辦呢?將格仔上的數在列方向做字首和,a i j 表示第j列,前i行格仔的權值和,b i j ...

bzoj3232 圈地遊戲

二分最小割。乙個答案可行要滿足 v c ans leq 0 將s向每個點連邊,流量為該點權值,相鄰兩個點連邊,流量為邊的費用 ans,邊界上的點向邊界外面連邊,流量也為相應費用 ans。可以發現,每一種割完連到s的點都是選了的點,選了的點和未選的點中間的邊的費用一定割了,未選的點的權值也沒有得到,所...