題目大概給乙個n×m的格仔,每個格仔有乙個一位數字,格仔不能重複經過,最多進行這樣的k次行走:每一次選擇任意乙個格仔出發,可以從當前格仔走到下面或右邊格仔,花費能量是曼哈頓距離-1,而如果起點和終點格仔數字一樣那就能獲得那個數字的能量。問能不能走過所有的格仔,如果能算出
最大的最終能量。
太弱了。。官方標算的構圖好難理解,好神的感覺。。而學習了另一種構圖方法,也好神:
這兒的m是乙個足夠大的值,比最大可能的最終能量大的值,我取1000,這樣放大(縮小。。)這條邊的費用是為了能盡量去走這條邊!
這樣最後求出最小費用cost,那麼如果-cost/1000不等於n*m那就無解,否則結果就是-cost%1000。
注意這兒的最小費用,不是要最大流條件下的最小費用,可以再加條vs'到匯點容量k費用0的邊,或者遇到非負的費用和就停止找增廣路。
感覺這種放大邊權的技巧太強了。
1 #include2 #include3 #include4 #include5using
namespace
std;
6#define inf (1<<30)
7#define maxn 222
8#define maxm 222*444
9struct
edgeedge[maxm];
12int
head[maxn];
13int
nv,ne,vs,vt;
1415
void addedge(int u,int v,int cap,int
cost)
21bool
vis[maxn];
22int
d[maxn],pre[maxn];
23bool
spfa()
28 vis[vs]=1
;29 d[vs]=0
;30 queueque;
31que.push(vs);
32while(!que.empty())43}
44}45 vis[u]=0;46
}47return d[vt]!=inf;48}
49int
mcmf()
56for(int u=vt; u!=vs; u=edge[pre[u]].u)
61if(cost>=0) break
;62 res+=cost;63}
64return
res;65}
66int
main()
74 vs=n*m*2+1; vt=vs+1; nv=vt+1; ne=0
;75 memset(head,-1,sizeof
(head));
76 addedge(vs,n*m*2,k,0
);77
for(int i=0; ii)
87for(int k=j+1; kk)92}
93}94int res=mcmf();
95if(-res/1000!=n*m) printf("
case %d : -1\n
",cse);
96else printf("
case %d : %d\n
",cse,-res%1000
);97}98
return0;
99 }
hdu 4862解題報告
看完題寫了個暴搜,果斷t了.dp的話複雜度太高了,只能用網路流求解 仔細分析是乙個費用流的模型,把費用取負就可以用最小費用流來跑了 費用流中的每條流就對應每次無限制的jump,按規則連好邊 關鍵問題就是如何讓所有點都被訪問一次 拆點後設流量為1,費用為 10 10 10 不可能達到的能量 還有就是設...
hdu 4862 Jump 最小費用流
之前也是看的解題報告寫的,所以寫的不好。現在回頭看看,其實很簡單。這篇我只作為筆記使用 14多校賽第一場題解 include include include include include include include include using namespace std define ll i...
HDU 4862 JUMP 最小費用最大流
2014 多校的b題,由於我不怎麼搞圖論,當時碰到這個題目,我怎麼想都沒往網路流方面弄,不過網路流真的是個好東西,對於狀態多變,無法用動規或者資料結構來很好表示的時候,非常有用 這個題目要求每個點一定要訪問到,並且每次訪問的是沒訪問過的點,跳躍的方向為向右或者向下。建圖的時候,分成二分圖,從乙個超級...