以s=0,t=n+m+1分別為超級源點和超級匯點。網路流中的流量以0為開始,題目要求從1到20,我們先把每個點都減去1,即ai - m,bi - n。然後源點s與n個頂點連容量為ai的路,匯點t與m個頂點連容量為bi的路,n個頂點再與m個頂點連線19的容量。最後再跑下dinic,如果最後匯聚到t的流量和總值相同,輸出「yes」,否則輸出「no」。最後輸出對應邊的答案,可以用殘餘網路來計算,用19-殘餘的容量即該條邊的流量。
1 #include 2 #include 3 #include 4 #include 5 #include 6using
namespace
std;78
const
int n=100;9
const
int m=n*n;
10const
int inf = 0x3f3f3f3f;11
ints,t,n,m,cnt;
12int
a[n],b[n];
13int
head[n],depth[n],next[m],v[m],w[m];
1415
void
init()
1621
22void add_edge(int u,int v,int
w)23
2728
bool
bfs()
2945}46
}47if(depth[t]==0)return
false;48
else
return
true;49
}5051int dfs(int u,int
flow)
5265}66
return flow-rest;67}
6869
intdinic()
7077
return
ans;78}
7980
void
print()
8190
for(int i=1;i<=n;i++)96}
97}9899
intmain()
108for(int i=1;i<=m;i++)
112113
for(int i=1;i<=n;i++)
114for(int j=1;j<=m;j++)
115 add_edge(i,n+j,19
);116
117int c1=0,c2=0,c3=0
;118
for(int i=1;i<=n;i++) c1+=a[i];
119for(int i=1;i<=m;i++) c2+=b[i];
120if(c1!=c2) printf("
no\n");
121else
128}
129return0;
130 }
附:edmonds-karp增廣路演算法模板: 不斷用bfs尋找增廣路,直至網路上不存在增廣路為止
1const
int inf = 1
<<29,n=2010,m=20010;2
inthead[n],ver[m],edge[m],next[m],v[n],incf[n],pre[n];
3int
n,m,s,t,tot,maxflow;45
void add(int x,int y,intz)6
1011
bool
bfs()
1233}34
}35return0;
36}3738
void update()//
更新一條增廣路及其反向邊的剩餘容量
3948 maxflow+=incf[t];49}
5051
intmain()
5263
while
(bfs())update();
64 cout66 }
SDOI2017 天才黑客
我們不妨思考一下,兩個串的 lcp 的長度在 trie 樹上是什麼?對應點的 lca 的深度。然後就可以想到把邊看成點,然後把邊與邊之間連邊,點權看成這條邊經過所需要的時間。但是這樣子連邊是 o m 2 的,不夠優秀。我們需要進一步優化。考慮兩個點之間的 lcp 可以用什麼來代替?sa 裡面的 he...
SDOI2017 天才黑客
這題太神了。先模claris 大神的題解。首先我們要將邊轉換為點。如果暴力連邊就會有 m 2 的邊,於是我們考慮優化建圖。難點在於快速得到兩個邊的串的 lcp 也就是 trie 樹上的 lca 我們將一堆點按 dfs 序排序,然後 a 到 b 的 lca 就是排序後 min 這裡的 min 是深度最...
SDOI2017 天才黑客
題目大意 給一張有向圖,再給一顆字典樹,有向圖上的每條邊有乙個非負邊權還有乙個字典樹上的字串,從一條邊到另一條邊的代價是那條邊的邊權和這兩個字串的最長公共字首,問從1到其他點的最短路 題解一看肯定是乙個最短路問題,現在的關鍵問題是如何把這張圖建出來。我們可以列舉每個點作為兩條邊的中轉點,然後直接把每...