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的點都是選了的點,選了的點和未選的點中間的邊的費用一定割了,未選的點的權值也沒有得到,所...