[关闭]
@Plutorabbit 2017-02-19T10:08:45.000000Z 字数 3916 阅读 2215

ZJOI 2016

ZJOI OI BZOJ 2016


BZOJ-4455 ~ BZOJ-4456


[Zjoi2016]小星星

讲道理这是T3,不知道为什么BZOJ上把T2T3倒着放QAQ
考场上只写了暴力,裸暴力QAQ
容斥&DP
枚举所有点和图中集合为的点对应的情况,然后答案就是和一一对应的情况

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int read()
  4. {
  5. int x=0; bool f=0; char ch;
  6. for (ch=getchar();ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=1;
  7. for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; if (f) x=-x;
  8. return x;
  9. }
  10. typedef long long LL;
  11. const int NN = 20;
  12. int all,bin[NN],p[NN],head[NN],n,m,tot;
  13. bool v[NN][NN];
  14. LL f[NN][NN],ans;
  15. struct E
  16. {
  17. int ne,v;
  18. }e[NN<<1];
  19. void Build(int xx,int yy)
  20. {
  21. e[++tot].ne = head[xx], head[xx] = tot, e[tot].v = yy;
  22. e[++tot].ne = head[yy], head[yy] = tot, e[tot].v = xx;
  23. }
  24. void DFS(int xx,int fa)
  25. {
  26. LL sum;
  27. for (int i=head[xx];i;i=e[i].ne)
  28. if (e[i].v != fa) DFS(e[i].v,xx);
  29. for (int i=1;i<=all;++i)
  30. {
  31. f[xx][i] = 1;
  32. for (int j=head[xx];j;j=e[j].ne)
  33. if (e[j].v != fa)
  34. {
  35. sum = 0ll;
  36. for (int k=1;k<=all;++k) if (v[p[i]][p[k]]) sum += f[e[j].v][k];
  37. f[xx][i] *= sum;
  38. }
  39. }
  40. }
  41. int main()
  42. {
  43. bin[1] = 1; for (int i=2;i<=18;++i) bin[i] = bin[i-1] << 1;
  44. n = read(), m = read();
  45. int x,y;
  46. for (int i=1;i<=m;++i) x = read(), y = read(), v[x][y] = v[y][x] = 1;
  47. for (int i=1;i<n;++i) x = read(), y = read(), Build(x,y);
  48. ans = 0ll;
  49. for (int i=0;i<(1<<n)-1;++i)
  50. {
  51. all = 0;
  52. for (int j=1;j<=n;++j)
  53. if (!(i&bin[j])) p[++all] = j;
  54. DFS(1,0);
  55. LL sum = 0;
  56. for (int j=1;j<=all;++j) sum += f[1][j];
  57. if ((n-all)&1) ans -= sum; else ans += sum;
  58. }
  59. printf("%lld\n",ans);
  60. return 0;
  61. }

[Zjoi2016]旅行者

感觉当时想到过一块一块来但完全不知道怎么搞QAQ
分治
有两种情况:
1.如果询问的起点和终点在不同的块,那么一定会经过中轴线上的一点;
2.如果在同一块,那么有可能经过中轴线;也有可能全部在那一块中;
这样就可以递归分治了
听说SPFA会被卡就难得写了次Dijkstra
每天STL用用没希望了,联赛被卡了还用QAQ

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int read()
  4. {
  5. int x=0; bool f=0; char ch;
  6. for (ch=getchar();ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=1;
  7. for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; if (f) x=-x;
  8. return x;
  9. }
  10. const int NN = 20010, MM = 100010, INF = 0x3f3f3f3f;
  11. struct Q
  12. {
  13. int x,len;
  14. friend bool operator < (Q xx,Q yy) { return xx.len > yy.len; }
  15. };
  16. priority_queue<Q> que;
  17. int px[NN],py[NN],dis[NN],head[NN],ans[MM],n,m,tot,QQ,w;
  18. bool vis[NN];
  19. struct E
  20. {
  21. int v,w,ne;
  22. }e[NN<<2];
  23. struct POI
  24. {
  25. int xa,xb,ya,yb,num;
  26. }p[MM],t[MM];
  27. void Build(int xx,int yy,int zz)
  28. {
  29. e[++tot].ne = head[xx], head[xx] = tot, e[tot].v = yy, e[tot].w = zz;
  30. e[++tot].ne = head[yy], head[yy] = tot, e[tot].v = xx, e[tot].w = zz;
  31. }
  32. int P(int xx,int yy) { return (xx-1)*m+yy; }
  33. void DIJ(int xx,int nl,int nr,int ml,int mr)
  34. {
  35. int t;
  36. for (int i=nl;i<=nr;++i)
  37. for (int j=ml;j<=mr;++j) t = P(i,j), dis[t] = INF, vis[t] = 0;
  38. dis[xx] = 0, que.push((Q){xx,0});
  39. while (!que.empty())
  40. {
  41. int now = que.top().x; que.pop();
  42. if (vis[now]) continue;
  43. vis[now] = 1;
  44. for (int i=head[now];i;i=e[i].ne)
  45. if (px[e[i].v]>=nl && px[e[i].v]<=nr && py[e[i].v]>=ml && py[e[i].v]<=mr)
  46. {
  47. if (dis[e[i].v] > dis[now] + e[i].w) dis[e[i].v] = dis[now] + e[i].w, que.push((Q){e[i].v,dis[e[i].v]});
  48. }
  49. }
  50. }
  51. void Solve(int nl,int nr,int ml,int mr,int ql,int qr)
  52. {
  53. if (ql > qr) return;
  54. if (nr-nl > mr-ml)
  55. {
  56. int mid = (nl+nr) >> 1;
  57. for (int i=ml;i<=mr;++i)
  58. {
  59. DIJ(P(mid,i),nl,nr,ml,mr);
  60. for (int j=ql;j<=qr;++j) ans[p[j].num] = min(ans[p[j].num],dis[P(p[j].xa,p[j].ya)]+dis[P(p[j].xb,p[j].yb)]);
  61. }
  62. int l = ql-1, r = qr+1;
  63. for (int i=ql;i<=qr;++i)
  64. if (p[i].xa<mid && p[i].xb<mid) t[++l] = p[i];
  65. else if (p[i].xa>mid && p[i].xb>mid) t[--r] = p[i];
  66. for (int i=ql;i<=l;++i) p[i] = t[i];
  67. for (int i=r;i<=qr;++i) p[i] = t[i];
  68. Solve(nl,mid-1,ml,mr,ql,l), Solve(mid+1,nr,ml,mr,r,qr);
  69. }
  70. else
  71. {
  72. int mid = (ml+mr) >> 1;
  73. for (int i=nl;i<=nr;++i)
  74. {
  75. DIJ(P(i,mid),nl,nr,ml,mr);
  76. for (int j=ql;j<=qr;++j) ans[p[j].num] = min(ans[p[j].num],dis[P(p[j].xa,p[j].ya)]+dis[P(p[j].xb,p[j].yb)]);
  77. }
  78. int l = ql-1, r = qr+1;
  79. for (int i=ql;i<=qr;++i)
  80. if (p[i].ya<mid && p[i].yb<mid) t[++l] = p[i];
  81. else if (p[i].ya>mid && p[i].yb>mid) t[--r] = p[i];
  82. for (int i=ql;i<=l;++i) p[i] = t[i];
  83. for (int i=r;i<=qr;++i) p[i] = t[i];
  84. Solve(nl,nr,ml,mid-1,ql,l), Solve(nl,nr,mid+1,mr,r,qr);
  85. }
  86. }
  87. int main()
  88. {
  89. n = read(), m = read();
  90. int x,y,z;
  91. for (int i=1;i<=n;++i)
  92. for (int j=1;j<=m;++j) x = P(i,j), px[x] = i, py[x] = j;
  93. for (int i=1;i<=n;++i)
  94. for (int j=1;j<m;++j)
  95. {
  96. x = P(i,j), y = P(i,j+1), z = read();
  97. Build(x,y,z);
  98. }
  99. for (int i=1;i<n;++i)
  100. for (int j=1;j<=m;++j)
  101. {
  102. x = P(i,j), y = P(i+1,j), z = read();
  103. Build(x,y,z);
  104. }
  105. QQ = read();
  106. for (int i=1;i<=QQ;++i)
  107. {
  108. ++w;
  109. p[w].xa = read(), p[w].ya = read(), p[w].xb = read(), p[w].yb = read();
  110. if (p[w].xa==p[w].xb && p[w].ya==p[w].yb) --w, ans[i] = 0; else p[w].num = i, ans[i] = INF;
  111. }
  112. Solve(1,n,1,m,1,w);
  113. for (int i=1;i<=QQ;++i) printf("%d\n",ans[i]);
  114. return 0;
  115. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注