[关闭]
@ZCDHJ 2019-10-23T11:42:37.000000Z 字数 1747 阅读 570

Codeforces241E Flights

差分约束


首先很显然对于任意在点 到点 路径上的点 ,所有从 的路径大小都是一样的。那么设 表示这个唯一的路径大小,对于每条合法边(两个端点都在 的路径上)有不等式:
看出来了吗?差分约束就行了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. #include <cstdlib>
  6. const int MAXN = 1000;
  7. const int MAXM = 5000;
  8. int n, m, edge;
  9. int U[MAXM | 1], V[MAXM | 1], fst[MAXN | 1], dist[MAXN | 1], cnt[MAXN | 1], flag[MAXN | 1];
  10. bool vis[MAXN | 1];
  11. struct Edge {
  12. int to, w, nxt;
  13. Edge() : to(0), w(0), nxt(0) {}
  14. Edge(int a, int b, int c) : to(b), w(c), nxt(fst[a]) {}
  15. } e[MAXM << 1 | 1];
  16. inline int read() {
  17. register int x = 0;
  18. register char ch = getchar();
  19. while (!isdigit(ch)) ch = getchar();
  20. while (isdigit(ch)) {
  21. x = x * 10 + ch - '0';
  22. ch = getchar();
  23. }
  24. return x;
  25. }
  26. inline void add_edge(int a, int b, int c) {
  27. e[++edge] = Edge(a, b, c);
  28. fst[a] = edge;
  29. }
  30. void dfs1(int x) {
  31. if (vis[x]) return;
  32. vis[x] = 1;
  33. flag[x] = 1;
  34. for (int k = fst[x]; k; k = e[k].nxt) {
  35. int to = e[k].to;
  36. if (e[k].w == 1) continue;
  37. dfs1(to);
  38. }
  39. }
  40. void dfs2(int x) {
  41. if (vis[x]) return;
  42. ++flag[x];
  43. vis[x] = 1;
  44. for (int k = fst[x]; k; k = e[k].nxt) {
  45. int to = e[k].to;
  46. if (e[k].w == 0) continue;
  47. dfs2(to);
  48. }
  49. }
  50. void SPFA() {
  51. std::queue < int > q;
  52. q.push(1);
  53. memset(dist, 0x3f, sizeof(dist));
  54. dist[1] = 0;
  55. do {
  56. int from = q.front();
  57. q.pop();
  58. vis[from] = 0;
  59. for (int k = fst[from]; k; k = e[k].nxt) {
  60. int to = e[k].to, w = e[k].w;
  61. if (dist[to] > dist[from] + w) {
  62. dist[to] = dist[from] + w;
  63. cnt[to] = cnt[from] + 1;
  64. if (cnt[to] > n) {
  65. puts("No");
  66. exit(0);
  67. }
  68. if (!vis[to]) {
  69. q.push(to);
  70. vis[to] = 1;
  71. }
  72. }
  73. }
  74. } while (!q.empty());
  75. }
  76. int main() {
  77. n = read();
  78. m = read();
  79. for (int i = 1; i <= m; ++i) {
  80. U[i] = read();
  81. V[i] = read();
  82. add_edge(V[i], U[i], 0);
  83. add_edge(U[i], V[i], 1);
  84. }
  85. dfs1(n);
  86. memset(vis, 0, sizeof(vis));
  87. dfs2(1);
  88. memset(vis, 0, sizeof(vis));
  89. edge = 0;
  90. memset(fst, 0, sizeof(fst));
  91. for (int i = 1; i <= m; ++i) {
  92. if (flag[U[i]] != 2 || flag[V[i]] != 2) continue;
  93. add_edge(U[i], V[i], 2);
  94. add_edge(V[i], U[i], -1);
  95. }
  96. SPFA();
  97. puts("Yes");
  98. for (int i = 1; i <= m; ++i) {
  99. if (flag[U[i]] != 2 || flag[V[i]] != 2) printf("1\n");
  100. else printf("%d\n", dist[V[i]] - dist[U[i]]);
  101. }
  102. return 0;
  103. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注