fork download
  1. #include "bits/stdc++.h"
  2.  
  3. #define clr(x) memset((x), 0, sizeof(x))
  4. #define all(x) (x).begin(), (x).end()
  5. #define pb push_back
  6. #define mp make_pair
  7. #define in(x) int (x); input((x));
  8. #define x first
  9. #define y second
  10. typedef int itn;
  11.  
  12. #define next next12345
  13. #define prev prev12345
  14. #define left lefdsf232
  15. #define right rig43783
  16. #define x1 x12345
  17. #define y1 y12345
  18.  
  19. using namespace std;
  20.  
  21. template<typename T>
  22. T gcd(T x, T y) {
  23. while (y > 0) {
  24. x %= y;
  25. swap(x, y);
  26. }
  27. return x;
  28. }
  29.  
  30. template<class _T>
  31. inline _T sqr(const _T &x) {
  32. return x * x;
  33. }
  34.  
  35. template<class _T>
  36. inline string tostr(const _T &a) {
  37. ostringstream os("");
  38. os << a;
  39. return os.str();
  40. }
  41.  
  42. typedef long double ld;
  43. typedef long long ll;
  44. typedef unsigned long long ull;
  45. typedef pair<int, int> PII;
  46. const long double PI = 3.1415926535897932384626433832795L;
  47.  
  48. template<typename T>
  49. inline void input(T &a) {
  50. static int c;
  51. a = 0;
  52. while (!isdigit(c = getchar()) && c != '-') {}
  53. char neg = 0;
  54. if (c == '-') {
  55. neg = 1;
  56. c = getchar();
  57. }
  58. while (isdigit(c)) {
  59. a = 10 * a + c - '0';
  60. c = getchar();
  61. }
  62. if (neg) a = -a;
  63. }
  64.  
  65. template<typename T = int>
  66. inline T nxt() {
  67. T res;
  68. input(res);
  69. return res;
  70. }
  71.  
  72. const int N = 30000;
  73.  
  74. struct dsu {
  75. int p[N];
  76. int sz[N];
  77. int cnt;
  78.  
  79. void init(int n) {
  80. for (int i = 0; i < n; ++i) {
  81. p[i] = i;
  82. sz[i] = 1;
  83. }
  84. cnt = n;
  85. }
  86.  
  87. inline int get(int v) {
  88. if (p[v] != v) {
  89. p[v] = get(p[v]);
  90. }
  91. return p[v];
  92. }
  93.  
  94. inline void unite(int a, int b) {
  95. a = get(a);
  96. b = get(b);
  97. if (a == b) {
  98. return;
  99. }
  100. --cnt;
  101. if (sz[a] > sz[b]) {
  102. swap(a, b);
  103. }
  104. p[a] = b;
  105. sz[b] += sz[a];
  106. }
  107. };
  108.  
  109. const int K = 17;
  110.  
  111. vector <dsu> x[K];
  112.  
  113. struct edge {
  114. int from;
  115. int to;
  116. int len;
  117. int id;
  118. bool operator<(const edge & e) const {
  119. return len < e.len;
  120. }
  121. };
  122.  
  123. int k;
  124.  
  125.  
  126. edge e[N];
  127.  
  128. dsu empty;
  129.  
  130. dsu W;
  131.  
  132. int vertices[N + N + N + N];
  133.  
  134. int check(int l, int r) {
  135. int p1 = (l + k - 1) / k;
  136. int p2 = (r + 1) / k;
  137.  
  138. int X = p1 * k;
  139. int Y = p2 * k;
  140.  
  141. p2 -= p1 + 1;
  142.  
  143. int sz = 0;
  144.  
  145. if (p2 < 0) {
  146. for (int x = l; x <= r; ++x) {
  147. int A = e[x].from;
  148. int B = e[x].to;
  149. if (A != B) {
  150. vertices[sz++] = A;
  151. vertices[sz++] = B;
  152. }
  153. }
  154.  
  155. W.cnt = empty.cnt;
  156. for (int i = 0; i < sz; ++i) {
  157. W.p[vertices[i]] = vertices[i];
  158. W.sz[vertices[i]] = 1;
  159. }
  160.  
  161. for (int x = l; x <= r; ++x) {
  162. int A = e[x].from;
  163. int B = e[x].to;
  164. if (A != B) W.unite(A, B);
  165. }
  166. } else {
  167. dsu & v = x[p1][p2];
  168.  
  169. for (int x = l; x < X; ++x) {
  170. int A = v.get(e[x].from);
  171. int B = v.get(e[x].to);
  172. if (A != B) {
  173. vertices[sz++] = A;
  174. vertices[sz++] = B;
  175. }
  176. }
  177.  
  178. for (int x = Y; x <= r; ++x) {
  179. int A = v.get(e[x].from);
  180. int B = v.get(e[x].to);
  181. if (A != B) {
  182. vertices[sz++] = A;
  183. vertices[sz++] = B;
  184. }
  185. }
  186.  
  187. W.cnt = v.cnt;
  188. for (int i = 0; i < sz; ++i) {
  189. W.p[vertices[i]] = vertices[i];
  190. W.sz[vertices[i]] = 1;
  191. }
  192.  
  193. for (int i = 0; i < sz; i += 2) {
  194. W.unite(vertices[i], vertices[i + 1]);
  195. }
  196. }
  197.  
  198. return W.cnt == 1;
  199. }
  200.  
  201. int main() {
  202. //#define int long
  203. #ifdef LOCAL
  204. freopen("input.txt", "r", stdin);
  205. //freopen("output.txt", "w", stdout);
  206. #else
  207. #define fname "onearmedbandit"
  208. //freopen(fname".in", "r", stdin);
  209. //freopen(fname".out", "w", stdout);
  210. #endif
  211.  
  212. int n = nxt(), m = nxt();
  213.  
  214. for (int i = 0; i < m; ++i) {
  215. e[i].from = nxt() - 1;
  216. e[i].to = nxt() - 1;
  217. e[i].len = nxt();
  218. e[i].id = i;
  219. }
  220.  
  221.  
  222. empty.init(n);
  223.  
  224. sort(e, e + m);
  225.  
  226. k = (m + K - 1) / K;
  227.  
  228.  
  229.  
  230. for (int i = 0, t = 0; i < m; i += k, ++t) {
  231. for (int j = i; j < m; ++j) {
  232. if (j % k == 0) {
  233. if (j == i) {
  234. x[t].push_back(dsu());
  235. x[t].back().init(n);
  236. } else {
  237. x[t].push_back(dsu());
  238. dsu & last = x[t][x[t].size() - 2];
  239. dsu & cur = x[t].back();
  240.  
  241. memcpy(cur.p, last.p, sizeof(int) * n);
  242. memcpy(cur.sz, last.sz, sizeof(int) * n);
  243. cur.cnt = last.cnt;
  244. }
  245. }
  246. x[t].back().unite(e[j].from, e[j].to);
  247. }
  248. }
  249.  
  250.  
  251. //cout << check(0, m - 1) << endl;
  252.  
  253. //return 0;
  254.  
  255.  
  256. int r = 0;
  257.  
  258. int best = INT_MAX;
  259.  
  260. int L = 0, R = m - 1;
  261.  
  262. for (int i = 0; i < m; ++i) {
  263. r = max(r, i + n - 2);
  264. while (r < m && !check(i, r)) {
  265. ++r;
  266. }
  267. if (r < m) {
  268. int v = e[r].len - e[i].len;
  269. if (v < best) {
  270. best = v;
  271. L = i, R = r;
  272. }
  273. } else {
  274. break;
  275. }
  276. }
  277.  
  278. vector <int> ans;
  279.  
  280. empty.init(n);
  281.  
  282. for (int x = L; x <= R; ++x) {
  283. int A = empty.get(e[x].from);
  284. int B = empty.get(e[x].to);
  285. if (A != B) {
  286. ans.push_back(e[x].id);
  287. empty.unite(A, B);
  288. }
  289. }
  290.  
  291. // long long mem = 0;
  292. // for (int i = 0; i < K; ++i) {
  293. // for (const auto & X : x[i]) {
  294. // mem += sizeof(X);
  295. // }
  296. // }
  297. //
  298. // cerr << mem << endl;
  299.  
  300. //cout << ans.size() << endl;
  301. assert(ans.size() == n - 1);
  302.  
  303. sort(all(ans));
  304.  
  305. for (int x : ans) {
  306. cout << x + 1 << " ";
  307. }
  308.  
  309. cout << "\n";
  310.  
  311. #ifdef LOCAL
  312. cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  313. #endif
  314. return 0;
  315. }
Time limit exceeded #stdin #stdout 5s 4668KB
stdin
Standard input is empty
stdout
Standard output is empty