今天写CF311E Biologist的时候忽然发现自己的ISAP一直跑不出一张图
然后一直调试无果后怀疑自己的ISAP
然后调了调发现——ISAP挂了
数据如下(附图片):
1 1 -> 23324 [label = " 5 "] 2 2 -> 23324 [label = " 10 "] 3 23323 -> 3 [label = " 8 "] 4 4 -> 23324 [label = " 5 "] 5 23323 -> 5 [label = " 4 "] 6 10012 -> 5 [label = " 1061109567 "] 7 10012 -> 4 [label = " 1061109567 "] 8 10012 -> 1 [label = " 1061109567 "] 9 23323 -> 10012 [label = " 7 "] 10 10013 -> 1 [label = " 1061109567 "] 11 10013 -> 3 [label = " 1061109567 "] 12 10013 -> 5 [label = " 1061109567 "] 13 23323 -> 10013 [label = " 10 "] 14 2 -> 10014 [label = " 1061109567 "] 15 1 -> 10014 [label = " 1061109567 "] 16 4 -> 10014 [label = " 1061109567 "] 17 10014 -> 23324 [label = " 8 "] 18 10015 -> 5 [label = " 1061109567 "] 19 10015 -> 2 [label = " 1061109567 "] 20 10015 -> 3 [label = " 1061109567 "] 21 23323 -> 10015 [label = " 0 "] 22 10016 -> 2 [label = " 1061109567 "] 23 10016 -> 4 [label = " 1061109567 "] 24 10016 -> 5 [label = " 1061109567 "] 25 23323 -> 10016 [label = " 7 "] 26 //这个是给画图软件用的数据
然后发现不止我的ISAP,还有其他几位DL的似乎也挂了
用了半年的板子......
ISAP板子如下:
1 struct Queue{ 2 int s, t; 3 int q[MAXN]; 4 Queue(){s = 1, t = 0;} 5 inline void clear(){ 6 s = 1, t = 0; 7 } 8 inline bool empty(){ 9 return s > t; 10 } 11 inline int size(){ 12 return t - s + 1; 13 } 14 inline void push(int tar){ 15 q[++ t] = tar; 16 } 17 inline int front(){ 18 return q[s]; 19 } 20 inline void pop(){ 21 s ++; 22 } 23 }; 24 25 struct Graph{ 26 int tot; 27 int beginx[MAXN], endx[MAXM], nxt[MAXM], res[MAXM]; 28 Graph(){ 29 tot = 1; 30 } 31 inline void Init(){ 32 tot = 1; 33 memset(beginx, 0, sizeof(beginx)); 34 } 35 inline void add_edge(int u, int v, int r){ 36 Debug(u, "->", v, "[label = \"", r, "\"]");//Debug... 37 nxt[++ tot] = beginx[u], beginx[u] = tot, endx[tot] = v, res[tot] = r; 38 nxt[++ tot] = beginx[v], beginx[v] = tot, endx[tot] = u, res[tot] = 0; 39 } 40 }ori; 41 42 struct ISap{ 43 Graph g; 44 Queue mession; 45 int max_f, now_f, pt; 46 int cur[MAXN], d[MAXN], num[MAXN], pre[MAXN]; 47 inline void BFS(){ 48 mession.clear(); 49 mession.push(t); 50 memset(d, 0, sizeof(d));//注意加了边之后一定要更新 51 memset(num, 0, sizeof(num)); 52 d[t] = 1; 53 int u, v; 54 while(!mession.empty()){ 55 u = mession.front(); 56 mession.pop(); 57 num[d[u]] ++; 58 for(int i = g.beginx[u]; i; i = g.nxt[i]){ 59 v = g.endx[i]; 60 if(!d[v] && g.res[i ^ 1]){//... 61 d[v] = d[u] + 1; 62 mession.push(v); 63 } 64 } 65 } 66 } 67 inline void argu(){ 68 while(pt != s){ 69 g.res[pre[pt]] -= now_f, g.res[pre[pt] ^ 1] += now_f; 70 pt = g.endx[pre[pt] ^ 1]; 71 } 72 max_f += now_f; 73 } 74 inline int ISAP(){ 75 max_f = 0, now_f = INF, pt = s; 76 BFS(); 77 memcpy(cur, g.beginx, sizeof(cur));//注意加了边之后一定要 78 bool done; 79 while(d[s] < MAXN - 5){ 80 if(pt == t) argu(), now_f = INF;//WTF?? 81 done = false; 82 for(int &i = cur[pt]; i; i = g.nxt[i]){ 83 int v = g.endx[i]; 84 if(g.res[i] && d[v] == d[pt] - 1){ 85 pre[v] = i; 86 pt = v;//... 87 done = true; 88 LKF::upmin(now_f, g.res[i]); 89 break; 90 } 91 } 92 if(!done){ 93 int heig = MAXN - 4; 94 for(int i = g.beginx[pt]; i; i = g.nxt[i]){ 95 int v = g.endx[i]; 96 if(g.res[i]) LKF::upmin(heig, d[v] + 1); 97 } 98 if(-- num[d[pt]] == 0) return max_f; 99 cur[pt] = g.beginx[pt]; 100 num[d[pt] = heig] ++; 101 if(pt != s) pt = g.endx[pre[pt] ^ 1]; 102 } 103 } 104 return max_f; 105 } 106 }isap;
初步原因观察到的是:
- now_f流量在回到了s之后没有被重置回INF
- 分层图有问题,会导致提前退出算法
有关原因待分析