-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy path16_Graph_Intro.html
More file actions
784 lines (706 loc) · 50 KB
/
16_Graph_Intro.html
File metadata and controls
784 lines (706 loc) · 50 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>16 图论基础:万物互联的模型</title>
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"/>
<style type="text/tailwindcss">
@theme {
--color-bg-dark: #030712;
--color-text-main: #f1f5f9;
--color-accent: #8b5cf6; /* Violet for Graph */
--color-secondary: #ec4899; /* Pink */
--color-tertiary: #06b6d4; /* Cyan */
--color-warn: #f59e0b;
--color-code-bg: #1e293b;
}
@layer base {
body { @apply bg-black text-text-main font-sans overflow-hidden flex justify-center items-center h-screen; }
}
@layer utilities {
.slide-container { @apply relative w-[1920px] h-[1080px] bg-bg-dark overflow-hidden shadow-2xl; }
.slide { @apply absolute inset-0 hidden flex-col p-14 opacity-0 transition-opacity duration-400 ease-in-out; }
.slide.active { @apply flex opacity-100; }
.bg-decoration { @apply absolute inset-0 z-0 pointer-events-none; background-image: radial-gradient(circle at 15% 15%, rgba(139,92,246,0.05) 0%, transparent 30%), radial-gradient(circle at 85% 85%, rgba(6,182,212,0.05) 0%, transparent 30%); }
.grid-overlay { @apply absolute inset-0 z-0; background-size: 60px 60px; background-image: linear-gradient(to right, rgba(255,255,255,0.02) 1px, transparent 1px), linear-gradient(to bottom, rgba(255,255,255,0.02) 1px, transparent 1px); }
h1 { @apply text-[100px] font-extrabold leading-tight mb-8; background: linear-gradient(135deg, #fff 0%, var(--color-accent) 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
h2 { @apply text-[64px] mb-8 text-accent inline-block pb-4 border-b-4 border-accent/30; }
h3 { @apply text-[42px] mb-6 text-secondary; }
p { @apply text-[32px] mb-4 text-slate-300; }
.slide-content li { @apply text-[32px] mb-4 text-slate-300; }
strong { @apply text-accent font-bold; }
.card { @apply bg-white/5 border border-white/10 rounded-3xl p-6 mb-6 backdrop-blur-sm; }
.code-block { @apply font-mono bg-code-bg p-6 rounded-2xl border border-slate-700 text-[22px] leading-relaxed text-slate-200 overflow-x-auto whitespace-pre; }
.code-kw { @apply text-[#c678dd]; }
.code-type { @apply text-[#e5c07b]; }
.code-cm { @apply text-[#64748b] italic; }
.code-num { @apply text-[#d19a66]; }
.btn-primary { @apply px-6 py-3 bg-accent/20 border border-accent/50 rounded-xl text-accent font-bold text-[24px] cursor-pointer transition-all hover:bg-accent/30 hover:scale-105 active:scale-95; }
.btn-secondary { @apply px-6 py-3 bg-slate-700/50 border border-slate-600 rounded-xl text-slate-300 font-bold text-[24px] cursor-pointer transition-all hover:bg-slate-600/50; }
}
</style>
</head>
<body>
<div id="app" class="slide-container">
<div class="bg-decoration"></div>
<div class="grid-overlay"></div>
<!-- P01: 封面 -->
<section class="slide active justify-center items-center text-center" data-title="封面">
<div class="flex flex-col items-center z-10 relative">
<!-- Animated Graph Decoration -->
<svg width="600" height="400" viewBox="0 0 600 400" class="mb-8 overflow-visible">
<defs>
<filter id="glow"><feGaussianBlur stdDeviation="4" result="coloredBlur"/><feMerge><feMergeNode in="coloredBlur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#8b5cf6;stop-opacity:1" /><stop offset="100%" style="stop-color:#06b6d4;stop-opacity:1" /></linearGradient>
</defs>
<!-- Edges -->
<g stroke="#475569" stroke-width="2" opacity="0.5">
<path d="M300 50 L100 200" /><path d="M300 50 L500 200" /><path d="M300 50 L300 350" />
<path d="M100 200 L500 200" /><path d="M100 200 L300 350" /><path d="M500 200 L300 350" />
</g>
<!-- Nodes -->
<g fill="url(#grad1)" filter="url(#glow)">
<circle cx="300" cy="50" r="20"><animate attributeName="r" values="20;25;20" dur="3s" repeatCount="indefinite"/></circle>
<circle cx="100" cy="200" r="20"><animate attributeName="r" values="20;25;20" dur="3s" begin="1s" repeatCount="indefinite"/></circle>
<circle cx="500" cy="200" r="20"><animate attributeName="r" values="20;25;20" dur="3s" begin="2s" repeatCount="indefinite"/></circle>
<circle cx="300" cy="350" r="20"><animate attributeName="r" values="20;25;20" dur="3s" begin="1.5s" repeatCount="indefinite"/></circle>
</g>
</svg>
<div class="bg-purple-500/10 px-6 py-2 rounded-full border border-purple-500/30 mb-6">
<span class="text-purple-400 text-2xl font-mono tracking-widest">GRAPH THEORY</span>
</div>
<h1>数据结构与算法</h1>
<p class="text-[56px] text-secondary">图 (Graph):万物互联</p>
</div>
</section>
<!-- P02: 实际价值 -->
<section class="slide" data-title="实际价值">
<h2>为什么要学图?</h2>
<div class="grid grid-cols-3 gap-8 h-full">
<!-- Row 1 -->
<div class="card flex flex-col items-center text-center border-slate-700 bg-slate-800/30 hover:bg-slate-700/30 transition-colors p-8">
<div class="text-[64px] text-accent mb-6"><i class="fas fa-users"></i></div>
<h3 class="text-white text-[36px] font-bold mb-4">社交网络</h3>
<p class="text-slate-400 text-[28px]">利用<strong>连通性</strong>做推荐,用<strong>BFS</strong>算六度分隔。</p>
</div>
<div class="card flex flex-col items-center text-center border-slate-700 bg-slate-800/30 hover:bg-slate-700/30 transition-colors p-8">
<div class="text-[64px] text-accent mb-6"><i class="fas fa-map-marked-alt"></i></div>
<h3 class="text-white text-[36px] font-bold mb-4">地图导航</h3>
<p class="text-slate-400 text-[28px]">将路口建模为顶点,用<strong>Dijkstra</strong>算最短路径。</p>
</div>
<div class="card flex flex-col items-center text-center border-slate-700 bg-slate-800/30 hover:bg-slate-700/30 transition-colors p-8">
<div class="text-[64px] text-accent mb-6"><i class="fas fa-project-diagram"></i></div>
<h3 class="text-white text-[36px] font-bold mb-4">任务调度</h3>
<p class="text-slate-400 text-[28px]">解析依赖关系,用<strong>拓扑排序</strong>决定执行顺序。</p>
</div>
<!-- Row 2 -->
<div class="card flex flex-col items-center text-center border-slate-700 bg-slate-800/30 hover:bg-slate-700/30 transition-colors p-8">
<div class="text-[64px] text-accent mb-6"><i class="fas fa-globe"></i></div>
<h3 class="text-white text-[36px] font-bold mb-4">互联网 (Web)</h3>
<p class="text-slate-400 text-[28px]">网页是顶点,链接是边,用<strong>PageRank</strong>算权重。</p>
</div>
<div class="card flex flex-col items-center text-center border-slate-700 bg-slate-800/30 hover:bg-slate-700/30 transition-colors p-8">
<div class="text-[64px] text-accent mb-6"><i class="fas fa-atom"></i></div>
<h3 class="text-white text-[36px] font-bold mb-4">知识图谱</h3>
<p class="text-slate-400 text-[28px]">实体间建立语义关联,支持<strong>复杂推理</strong>。</p>
</div>
<div class="card flex flex-col items-center text-center border-slate-700 bg-slate-800/30 hover:bg-slate-700/30 transition-colors p-8">
<div class="text-[64px] text-accent mb-6"><i class="fas fa-network-wired"></i></div>
<h3 class="text-white text-[36px] font-bold mb-4">网络拓扑</h3>
<p class="text-slate-400 text-[28px]">用<strong>最小生成树</strong>优化布线成本或路由广播。</p>
</div>
</div>
</section>
<!-- P03: 什么是图 -->
<section class="slide" data-title="定义与对比">
<h2>什么是图 (Graph)?</h2>
<div class="grid grid-cols-2 gap-12 h-full">
<div class="flex flex-col justify-center">
<div class="card p-8 border-slate-700 bg-slate-800/30">
<h3 class="text-accent text-[40px] mb-6"><i class="fas fa-quote-left mr-4"></i>定义</h3>
<p class="text-[36px] text-white leading-relaxed">
图是由<strong class="text-white">顶点 (Vertex)</strong> 的有穷非空集合和顶点之间的<strong class="text-white">边 (Edge)</strong> 集合组成的数据结构。
</p>
<div class="mt-8 p-6 bg-black/40 rounded-xl border border-slate-600 font-mono text-[32px] text-center text-accent">
G = (V, E)
</div>
</div>
<div class="mt-8">
<h4 class="text-[38px] text-slate-300 mb-4"><i class="fas fa-lightbulb text-accent mr-3"></i>核心本质</h4>
<p class="text-[32px] text-slate-400">表示 <strong class="text-white">"多对多" (Many-to-Many)</strong> 的关系。</p>
</div>
</div>
<div class="flex flex-col justify-center space-y-8">
<!-- Linear -->
<div class="flex items-center p-8 bg-slate-800/30 rounded-2xl border border-slate-700">
<div class="w-1/3 text-center border-r border-slate-600 pr-6">
<div class="text-[36px] text-slate-400">线性表</div>
<div class="text-[28px] text-slate-500">1 对 1</div>
</div>
<div class="w-2/3 pl-10">
<svg width="300" height="80" viewBox="0 0 300 80">
<circle cx="30" cy="40" r="15" fill="#94a3b8"/>
<line x1="45" y1="40" x2="95" y2="40" stroke="#475569" stroke-width="3"/>
<circle cx="110" cy="40" r="15" fill="#94a3b8"/>
<line x1="125" y1="40" x2="175" y2="40" stroke="#475569" stroke-width="3"/>
<circle cx="190" cy="40" r="15" fill="#94a3b8"/>
</svg>
</div>
</div>
<!-- Tree -->
<div class="flex items-center p-8 bg-slate-800/30 rounded-2xl border border-slate-700">
<div class="w-1/3 text-center border-r border-slate-600 pr-6">
<div class="text-[36px] text-slate-400">树 (Tree)</div>
<div class="text-[28px] text-slate-500">1 对 多</div>
</div>
<div class="w-2/3 pl-10">
<svg width="300" height="140" viewBox="0 0 300 140">
<circle cx="150" cy="25" r="15" fill="#cbd5e1"/>
<line x1="150" y1="40" x2="90" y2="110" stroke="#475569" stroke-width="3"/>
<line x1="150" y1="40" x2="210" y2="110" stroke="#475569" stroke-width="3"/>
<circle cx="90" cy="110" r="15" fill="#cbd5e1"/>
<circle cx="210" cy="110" r="15" fill="#cbd5e1"/>
</svg>
</div>
</div>
<!-- Graph -->
<div class="flex items-center p-8 bg-accent/10 rounded-2xl border border-accent/50">
<div class="w-1/3 text-center border-r border-accent/30 pr-6">
<div class="text-[36px] text-accent font-bold">图 (Graph)</div>
<div class="text-[28px] text-slate-300">多 对 多</div>
</div>
<div class="w-2/3 pl-10">
<svg width="300" height="160" viewBox="0 0 300 160">
<path d="M50 30 L250 30 L150 130 Z" stroke="#8b5cf6" stroke-width="3" fill="none"/>
<circle cx="50" cy="30" r="18" fill="#8b5cf6"/>
<circle cx="250" cy="30" r="18" fill="#8b5cf6"/>
<circle cx="150" cy="130" r="18" fill="#8b5cf6"/>
<path d="M50 30 L150 130" stroke="#8b5cf6" stroke-width="3"/>
</svg>
</div>
</div>
</div>
</div>
</section>
<!-- P04: 课程路线图 -->
<section class="slide" data-title="课程路线图">
<h2>图论课程路线图</h2>
<div class="flex items-center justify-center h-full">
<div class="grid grid-cols-3 gap-10 w-full max-w-[1700px]">
<!-- L1 -->
<div class="card bg-slate-800/50 border-slate-700 h-[380px] flex flex-col justify-center items-center">
<div class="text-[90px] text-accent mb-6"><i class="fas fa-project-diagram"></i></div>
<p class="text-slate-200 text-[42px] font-bold">图论基础</p>
<p class="text-slate-400 text-[30px] mt-3">顶点、边、度、权重、方向</p>
</div>
<!-- L2 -->
<div class="card bg-slate-800/50 border-slate-700 h-[380px] flex flex-col justify-center items-center">
<div class="text-[90px] text-accent mb-6"><i class="fas fa-database"></i></div>
<p class="text-slate-200 text-[42px] font-bold">图的存储</p>
<p class="text-slate-400 text-[30px] mt-3">邻接矩阵 & 邻接表</p>
</div>
<!-- L3 -->
<div class="card bg-slate-800/50 border-slate-700 h-[380px] flex flex-col justify-center items-center">
<div class="text-[90px] text-accent mb-6"><i class="fas fa-search-location"></i></div>
<p class="text-slate-200 text-[42px] font-bold">图的遍历</p>
<p class="text-slate-400 text-[30px] mt-3">BFS & DFS</p>
</div>
<!-- L4 -->
<div class="card bg-slate-800/50 border-slate-700 h-[380px] flex flex-col justify-center items-center">
<div class="text-[90px] text-accent mb-6"><i class="fas fa-tree"></i></div>
<p class="text-slate-200 text-[42px] font-bold">最小生成树</p>
<p class="text-slate-400 text-[30px] mt-3">Prim & Kruskal</p>
</div>
<!-- L5 -->
<div class="card bg-slate-800/50 border-slate-700 h-[380px] flex flex-col justify-center items-center">
<div class="text-[90px] text-accent mb-6"><i class="fas fa-route"></i></div>
<p class="text-slate-200 text-[42px] font-bold">最短路径</p>
<p class="text-slate-400 text-[30px] mt-3">Dijkstra & Floyd</p>
</div>
<!-- L6 -->
<div class="card bg-slate-800/50 border-slate-700 h-[380px] flex flex-col justify-center items-center">
<div class="text-[90px] text-accent mb-6"><i class="fas fa-flag-checkered"></i></div>
<p class="text-slate-200 text-[42px] font-bold">关键路径</p>
<p class="text-slate-400 text-[30px] mt-3">拓扑排序 & AOE网</p>
</div>
</div>
</div>
</section>
<!-- P05: 核心概念1 - 顶点与边 -->
<section class="slide" data-title="概念:方向">
<h2>无向图 vs 有向图</h2>
<div class="grid grid-cols-2 gap-16 h-full items-center px-12">
<!-- Undirected -->
<div class="card border-slate-700 bg-slate-800/30 relative overflow-hidden group p-10">
<div class="absolute top-0 right-0 bg-slate-700 px-6 py-3 rounded-bl-2xl text-slate-200 font-bold text-[28px]">无向图 (Undirected)</div>
<div class="flex justify-center my-10">
<svg width="450" height="300" viewBox="0 0 450 300">
<!-- Edges -->
<line x1="225" y1="50" x2="320" y2="120" stroke="#a855f7" stroke-width="3" />
<line x1="320" y1="120" x2="290" y2="230" stroke="#a855f7" stroke-width="3" />
<line x1="290" y1="230" x2="160" y2="230" stroke="#a855f7" stroke-width="3" />
<line x1="160" y1="230" x2="130" y2="120" stroke="#a855f7" stroke-width="3" />
<line x1="130" y1="120" x2="225" y2="50" stroke="#a855f7" stroke-width="3" />
<line x1="225" y1="50" x2="290" y2="230" stroke="#a855f7" stroke-width="3" />
<line x1="130" y1="120" x2="290" y2="230" stroke="#a855f7" stroke-width="3" />
<!-- Nodes -->
<circle cx="225" cy="50" r="25" fill="#581c87" stroke="#a855f7" stroke-width="3"/>
<text x="225" y="58" text-anchor="middle" fill="#fff" font-size="20">A</text>
<circle cx="320" cy="120" r="25" fill="#581c87" stroke="#a855f7" stroke-width="3"/>
<text x="320" y="128" text-anchor="middle" fill="#fff" font-size="20">B</text>
<circle cx="290" cy="230" r="25" fill="#581c87" stroke="#a855f7" stroke-width="3"/>
<text x="290" y="238" text-anchor="middle" fill="#fff" font-size="20">C</text>
<circle cx="160" cy="230" r="25" fill="#581c87" stroke="#a855f7" stroke-width="3"/>
<text x="160" y="238" text-anchor="middle" fill="#fff" font-size="20">D</text>
<circle cx="130" cy="120" r="25" fill="#581c87" stroke="#a855f7" stroke-width="3"/>
<text x="130" y="128" text-anchor="middle" fill="#fff" font-size="20">E</text>
</svg>
</div>
<ul class="space-y-6 text-[36px]">
<li class="flex items-start"><i class="fas fa-check text-accent mt-3 mr-4"></i><span>边没有方向,是对称的。</span></li>
<li class="flex items-start"><i class="fas fa-code text-slate-500 mt-3 mr-4"></i><span class="font-mono text-slate-300">(A, B) 等同于 (B, A)</span></li>
<li class="flex items-start"><i class="fas fa-example text-slate-500 mt-3 mr-4"></i><span>例子:微信好友,握手。</span></li>
</ul>
</div>
<!-- Directed -->
<div class="card border-slate-700 bg-slate-800/30 relative overflow-hidden p-10">
<div class="absolute top-0 right-0 bg-slate-700 px-6 py-3 rounded-bl-2xl text-slate-200 font-bold text-[28px]">有向图 (Directed)</div>
<div class="flex justify-center my-10">
<svg width="450" height="300" viewBox="0 0 450 300">
<defs>
<marker id="arrow-pink" markerWidth="10" markerHeight="10" refX="18" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#8b5cf6" />
</marker>
</defs>
<!-- Edges -->
<line x1="225" y1="50" x2="320" y2="120" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<line x1="320" y1="120" x2="290" y2="230" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<line x1="290" y1="230" x2="160" y2="230" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<line x1="160" y1="230" x2="130" y2="120" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<line x1="130" y1="120" x2="225" y2="50" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<line x1="225" y1="50" x2="290" y2="230" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<line x1="160" y1="230" x2="225" y2="50" stroke="#8b5cf6" stroke-width="3" marker-end="url(#arrow-pink)"/>
<!-- Nodes -->
<circle cx="225" cy="50" r="25" fill="#4c1d95" stroke="#8b5cf6" stroke-width="3"/>
<text x="225" y="58" text-anchor="middle" fill="#fff" font-size="20">A</text>
<circle cx="320" cy="120" r="25" fill="#4c1d95" stroke="#8b5cf6" stroke-width="3"/>
<text x="320" y="128" text-anchor="middle" fill="#fff" font-size="20">B</text>
<circle cx="290" cy="230" r="25" fill="#4c1d95" stroke="#8b5cf6" stroke-width="3"/>
<text x="290" y="238" text-anchor="middle" fill="#fff" font-size="20">C</text>
<circle cx="160" cy="230" r="25" fill="#4c1d95" stroke="#8b5cf6" stroke-width="3"/>
<text x="160" y="238" text-anchor="middle" fill="#fff" font-size="20">D</text>
<circle cx="130" cy="120" r="25" fill="#4c1d95" stroke="#8b5cf6" stroke-width="3"/>
<text x="130" y="128" text-anchor="middle" fill="#fff" font-size="20">E</text>
</svg>
</div>
<ul class="space-y-6 text-[36px]">
<li class="flex items-start"><i class="fas fa-check text-accent mt-3 mr-4"></i><span>边有方向,不对称。</span></li>
<li class="flex items-start"><i class="fas fa-code text-slate-500 mt-3 mr-4"></i><span class="font-mono text-slate-300"><A, B> 不等于 <B, A></span></li>
<li class="flex items-start"><i class="fas fa-example text-slate-500 mt-3 mr-4"></i><span>例子:微博关注,网页链接。</span></li>
</ul>
</div>
</div>
</section>
<!-- P06: 核心概念2 - 度 -->
<section class="slide" data-title="概念:度">
<h2>顶点的度 (Degree)</h2>
<div class="grid grid-cols-2 gap-16 h-full">
<!-- Undirected Degree -->
<div class="card bg-slate-800/30 border-slate-700 p-8 flex flex-col">
<h3 class="text-white text-[40px] mb-6 border-b border-slate-700 pb-4">无向图 (Undirected)</h3>
<p class="text-[32px] mb-8">度 = 与该顶点相连的边的数量。</p>
<div class="flex-1 flex items-center justify-center bg-black/30 rounded-2xl relative">
<svg width="300" height="310" viewBox="0 0 300 310">
<line x1="150" y1="150" x2="50" y2="50" stroke="#60a5fa" stroke-width="4" />
<line x1="150" y1="150" x2="250" y2="50" stroke="#60a5fa" stroke-width="4" />
<line x1="150" y1="150" x2="150" y2="280" stroke="#60a5fa" stroke-width="4" />
<!-- Other Nodes (Opacity 0.5) -->
<circle cx="50" cy="50" r="20" fill="#0f172a" stroke="#60a5fa" stroke-width="4""/>
<circle cx="250" cy="50" r="20" fill="#0f172a" stroke="#60a5fa" stroke-width="4""/>
<circle cx="150" cy="280" r="20" fill="#0f172a" stroke="#60a5fa" stroke-width="4""/>
<circle cx="150" cy="150" r="40" fill="#0f172a" stroke="#60a5fa" stroke-width="4"/>
<text x="150" y="165" text-anchor="middle" fill="#fff" font-size="36" font-weight="bold">V</text>
</svg>
<div class="absolute bottom-6 bg-slate-900/80 px-6 py-2 rounded-full border border-slate-700">
<span class="text-slate-300 text-[32px] font-mono">Degree(V) = 3</span>
</div>
</div>
</div>
<!-- Directed Degree -->
<div class="card bg-slate-800/30 border-slate-700 p-8 flex flex-col">
<h3 class="text-white text-[40px] mb-6 border-b border-slate-700 pb-4">有向图 (Directed)</h3>
<div class="space-y-6 mb-8">
<div class="flex items-center">
<div class="w-4 h-4 rounded-full bg-blue-400 mr-4"></div>
<p class="text-[30px] m-0"><strong class="text-blue-400">入度 (In-degree)</strong>: 指向本顶线的边数量</p>
</div>
<div class="flex items-center">
<div class="w-4 h-4 rounded-full bg-purple-400 mr-4"></div>
<p class="text-[30px] m-0"><strong class="text-purple-400">出度 (Out-degree)</strong>: 从本顶点指向其他顶点的边数量</p>
</div>
<p class="text-[28px] text-slate-400 pl-8">总度数 = 入度 + 出度</p>
</div>
<div class="flex-1 flex items-center justify-center bg-black/30 rounded-2xl relative">
<svg width="400" height="300" viewBox="0 0 400 300">
<defs>
<marker id="arrow-in" markerWidth="8" markerHeight="8" refX="9" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#60a5fa" />
</marker>
<marker id="arrow-out" markerWidth="8" markerHeight="8" refX="9" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#c084fc" />
</marker>
</defs>
<!-- Incoming -->
<line x1="67" y1="61" x2="167" y2="128" stroke="#60a5fa" stroke-width="3" marker-end="url(#arrow-in)"/>
<line x1="67" y1="239" x2="167" y2="172" stroke="#60a5fa" stroke-width="3" marker-end="url(#arrow-in)"/>
<!-- Outgoing -->
<line x1="240" y1="150" x2="330" y2="150" stroke="#c084fc" stroke-width="3" marker-end="url(#arrow-out)"/>
<!-- Other Nodes (Opaque) -->
<circle cx="50" cy="50" r="20" fill="#0f172a" stroke="#94a3b8" stroke-width="4"/>
<circle cx="50" cy="250" r="20" fill="#0f172a" stroke="#94a3b8" stroke-width="4"/>
<circle cx="350" cy="150" r="20" fill="#0f172a" stroke="#94a3b8" stroke-width="4"/>
<!-- Center Node -->
<circle cx="200" cy="150" r="40" fill="#1e293b" stroke="#94a3b8" stroke-width="4"/>
<text x="200" y="165" text-anchor="middle" fill="#fff" font-size="36" font-weight="bold">V</text>
</svg>
<div class="absolute bottom-4 flex gap-4">
<div class="bg-slate-900/80 px-4 py-2 rounded-lg border border-blue-500/50">
<span class="text-blue-400 text-[24px] font-mono">In: 2</span>
</div>
<div class="bg-slate-900/80 px-4 py-2 rounded-lg border border-purple-500/50">
<span class="text-purple-400 text-[24px] font-mono">Out: 1</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- P07: 核心概念3 - 权重 -->
<section class="slide" data-title="概念:权重">
<h2>边的权重 (Weight)</h2>
<div class="grid grid-cols-2 gap-12 h-full items-center">
<div class="flex flex-col gap-8">
<div class="card border-l-8 border-slate-600 p-8">
<h3 class="text-accent text-[40px] mb-4">定义</h3>
<p class="text-[32px] text-white leading-relaxed">
赋予边的数值,代表两个顶点之间关系的<strong class="text-accent">强度</strong>或<strong class="text-accent">成本</strong>。
</p>
</div>
<div class="card bg-slate-800/30 p-8">
<h3 class="text-slate-300 text-[32px] mb-6"><i class="fas fa-tags mr-4 text-slate-500"></i>常见含义</h3>
<ul class="space-y-4">
<li class="flex items-center text-[28px]"><span class="w-32 text-slate-400">地图:</span> <span class="text-white">距离 (km)、时间 (min)</span></li>
<li class="flex items-center text-[28px]"><span class="w-32 text-slate-400">网络:</span> <span class="text-white">带宽 (Mbps)、延迟 (ms)</span></li>
<li class="flex items-center text-[28px]"><span class="w-32 text-slate-400">社交:</span> <span class="text-white">亲密度、互动频率</span></li>
</ul>
</div>
<div class="bg-slate-800/30 border border-slate-700 p-6 rounded-xl text-center">
<p class="text-[28px] text-slate-300">
带权图 (Weighted Graph) 又称为 <strong class="text-white">网 (Network)</strong>
</p>
</div>
</div>
<!-- Visual Demo -->
<div class="card bg-black/20 flex flex-col items-center justify-center h-full relative overflow-hidden">
<div class="absolute top-4 left-6 text-slate-500 text-[24px] font-mono">Example: 城市间距离</div>
<svg width="600" height="500" viewBox="0 0 600 500">
<defs>
<marker id="arrow-weight" markerWidth="10" markerHeight="10" refX="22" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#a855f7" />
</marker>
</defs>
<!-- Edges with Weights -->
<!-- A -> B -->
<line x1="150" y1="100" x2="450" y2="100" stroke="#8b5cf6" stroke-width="4" />
<rect x="270" y="80" width="60" height="40" rx="6" fill="#1e293b" stroke="#8b5cf6"/>
<text x="300" y="108" text-anchor="middle" fill="#a855f7" font-size="20" font-weight="bold">800</text>
<!-- A -> C -->
<line x1="150" y1="100" x2="300" y2="350" stroke="#8b5cf6" stroke-width="4" />
<rect x="190" y="210" width="60" height="40" rx="6" fill="#1e293b" stroke="#8b5cf6"/>
<text x="220" y="238" text-anchor="middle" fill="#a855f7" font-size="20" font-weight="bold">500</text>
<!-- B -> C -->
<line x1="450" y1="100" x2="300" y2="350" stroke="#8b5cf6" stroke-width="4" />
<rect x="340" y="210" width="60" height="40" rx="6" fill="#1e293b" stroke="#8b5cf6"/>
<text x="370" y="238" text-anchor="middle" fill="#a855f7" font-size="20" font-weight="bold">300</text>
<!-- Nodes -->
<circle cx="150" cy="100" r="30" fill="#1e293b" stroke="#fff" stroke-width="3"/>
<text x="150" y="110" text-anchor="middle" fill="#fff" font-size="24">北京</text>
<circle cx="450" cy="100" r="30" fill="#1e293b" stroke="#fff" stroke-width="3"/>
<text x="450" y="110" text-anchor="middle" fill="#fff" font-size="24">上海</text>
<circle cx="300" cy="350" r="30" fill="#1e293b" stroke="#fff" stroke-width="3"/>
<text x="300" y="360" text-anchor="middle" fill="#fff" font-size="24">武汉</text>
</svg>
</div>
</div>
</section>
<!-- P08: 核心概念3 - 路径与环 -->
<section class="slide" data-title="概念:路径与环">
<h2>路径 (Path) & 环 (Cycle)</h2>
<div class="grid grid-cols-2 gap-12 h-full">
<div class="flex flex-col justify-center gap-8">
<div class="card border-l-8 border-slate-600 p-8">
<h3 class="text-white text-[40px] mb-4">路径 (Path)</h3>
<p class="text-[32px] text-slate-200 mb-4">从一个顶点到另一个顶点,途径的顶点序列</p>
<div class="text-[24px] text-white bg-bg-dark p-4 rounded-lg inline-block">简单路径:不重复经过顶点的路径。</div>
</div>
<div class="card border-l-8 border-slate-600 p-8">
<h3 class="text-white text-[40px] mb-4">环 (Cycle)</h3>
<p class="text-[32px] text-slate-200">起点和终点相同的路径。</p>
<p class="text-[28px] text-slate-500 mt-4">例如:A -> B -> E -> A</p>
</div>
</div>
<!-- Visual: Path & Cycle -->
<div class="card bg-black/20 flex items-center justify-center relative">
<svg width="700" height="500" viewBox="0 0 700 500">
<defs>
<marker id="arrow-gray" markerWidth="12" markerHeight="12" refX="19" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#475569" />
</marker>
</defs>
<!-- Edges Layer -->
<g>
<!-- Cross Edges -->
<line x1="250" y1="100" x2="350" y2="400" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)" /> <!-- B->E -->
<line x1="450" y1="100" x2="100" y2="250" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)" /> <!-- C->A -->
<!-- Cycle Edges (A->B->C->D->E->A) -->
<!-- A->B -->
<line x1="100" y1="250" x2="250" y2="100" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)">
<animate attributeName="stroke" values="#475569;#8b5cf6;#8b5cf6;#475569" keyTimes="0;0.1;0.9;1" dur="10s" begin="0s" repeatCount="indefinite" />
</line>
<!-- B->C -->
<line x1="250" y1="100" x2="450" y2="100" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)">
<animate attributeName="stroke" values="#475569;#475569;#8b5cf6;#8b5cf6;#475569" keyTimes="0;0.1;0.2;0.9;1" dur="10s" begin="0s" repeatCount="indefinite" />
</line>
<!-- C->D -->
<line x1="450" y1="100" x2="600" y2="250" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)">
<animate attributeName="stroke" values="#475569;#475569;#8b5cf6;#8b5cf6;#475569" keyTimes="0;0.2;0.3;0.9;1" dur="10s" begin="0s" repeatCount="indefinite" />
</line>
<!-- D->E -->
<line x1="600" y1="250" x2="350" y2="400" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)">
<animate attributeName="stroke" values="#475569;#475569;#8b5cf6;#8b5cf6;#475569" keyTimes="0;0.3;0.4;0.9;1" dur="10s" begin="0s" repeatCount="indefinite" />
</line>
<!-- E->A -->
<line x1="350" y1="400" x2="100" y2="250" stroke="#475569" stroke-width="3" marker-end="url(#arrow-gray)">
<animate attributeName="stroke" values="#475569;#475569;#8b5cf6;#8b5cf6;#475569" keyTimes="0;0.4;0.5;0.9;1" dur="10s" begin="0s" repeatCount="indefinite" />
</line>
</g>
<!-- Nodes Layer -->
<g>
<circle cx="100" cy="250" r="30" fill="#1e293b" stroke="#fff" stroke-width="2"/>
<text x="100" y="260" text-anchor="middle" fill="#fff" font-size="24">A</text>
<circle cx="250" cy="100" r="30" fill="#1e293b" stroke="#fff" stroke-width="2"/>
<text x="250" y="110" text-anchor="middle" fill="#fff" font-size="24">B</text>
<circle cx="450" cy="100" r="30" fill="#1e293b" stroke="#fff" stroke-width="2"/>
<text x="450" y="110" text-anchor="middle" fill="#fff" font-size="24">C</text>
<circle cx="600" cy="250" r="30" fill="#1e293b" stroke="#fff" stroke-width="2"/>
<text x="600" y="260" text-anchor="middle" fill="#fff" font-size="24">D</text>
<circle cx="350" cy="400" r="30" fill="#1e293b" stroke="#fff" stroke-width="2"/>
<text x="350" y="410" text-anchor="middle" fill="#fff" font-size="24">E</text>
</g>
<text x="350" y="480" text-anchor="middle" fill="#8b5cf6" font-size="28">环 (Cycle): A -> B -> C -> D -> E -> A</text>
</svg>
</div>
</div>
</section>
<!-- P09: 核心概念4 - 连通性 -->
<section class="slide" data-title="概念:连通性">
<h2>连通性 (Connectivity)</h2>
<div class="flex flex-col h-full gap-6">
<!-- Top: Concepts (Horizontal Layout) -->
<div class="grid grid-cols-3 gap-6">
<div class="card border-l-8 border-tertiary p-6 bg-slate-800/40">
<h3 class="text-white text-[32px] mb-2 font-bold">连通 (Connected)</h3>
<p class="text-[24px] text-slate-300 leading-normal">顶点之间存在路径即为连通。</p>
</div>
<div class="card border-l-8 border-blue-400 p-6 bg-slate-800/40">
<h3 class="text-white text-[32px] mb-2 font-bold">连通图 (Undirected)</h3>
<p class="text-[24px] text-slate-300 leading-normal">任意两点连通,若不连通则包含多个"连通分量"。</p>
</div>
<div class="card border-l-8 border-pink-400 p-6 bg-slate-800/40">
<h3 class="text-white text-[32px] mb-2 font-bold">强连通 (Directed)</h3>
<p class="text-[24px] text-slate-300 leading-normal">有向图中,任意两个顶点之间都可以互相到达。</p>
</div>
</div>
<!-- Bottom: Visuals (Side by Side, Larger) -->
<div class="flex-1 grid grid-cols-2 gap-8">
<!-- Left: Undirected -->
<div class="card bg-slate-800/20 border border-slate-700/50 rounded-2xl relative flex flex-col overflow-hidden">
<div class="absolute top-4 left-6 px-4 py-1 bg-slate-700/50 rounded-lg text-slate-300 text-[24px] font-bold border border-slate-600">无向图</div>
<div class="flex-1 flex items-center justify-around px-4">
<!-- Connected Graph Example -->
<div class="flex flex-col items-center gap-4">
<svg width="240" height="240" viewBox="0 0 240 240" class="overflow-visible">
<g stroke="#06b6d4" stroke-width="3">
<path d="M120 40 L50 100 L70 190 L170 190 L190 100 Z" fill="none"/>
</g>
<g fill="#0e7490" stroke="#22d3ee" stroke-width="3">
<circle cx="120" cy="40" r="16"/>
<circle cx="50" cy="100" r="16"/>
<circle cx="70" cy="190" r="16"/>
<circle cx="170" cy="190" r="16"/>
<circle cx="190" cy="100" r="16"/>
</g>
</svg>
<span class="text-cyan-400 text-[26px] font-bold">连通图</span>
</div>
<!-- Divider -->
<div class="h-[60%] w-0 border-r-2 border-dashed border-slate-600/50"></div>
<!-- Disconnected Graph Example -->
<div class="flex flex-col items-center gap-4">
<svg width="240" height="240" viewBox="0 0 240 240" class="overflow-visible">
<!-- Component 1 -->
<g stroke="#f472b6" stroke-width="3">
<path d="M70 60 L40 140 L100 140 Z" fill="none"/>
</g>
<g fill="#be185d" stroke="#f472b6" stroke-width="3">
<circle cx="70" cy="60" r="16"/>
<circle cx="40" cy="140" r="16"/>
<circle cx="100" cy="140" r="16"/>
</g>
<!-- Component 2 -->
<g stroke="#a855f7" stroke-width="3">
<line x1="160" y1="80" x2="200" y2="160" />
</g>
<g fill="#7e22ce" stroke="#a855f7" stroke-width="3">
<circle cx="160" cy="80" r="16"/>
<circle cx="200" cy="160" r="16"/>
</g>
</svg>
<span class="text-pink-400 text-[26px] font-bold">非连通图</span>
</div>
</div>
</div>
<!-- Right: Directed -->
<div class="card bg-slate-800/20 border border-slate-700/50 rounded-2xl relative flex flex-col items-center justify-center overflow-hidden">
<div class="absolute top-4 left-6 px-4 py-1 bg-slate-700/50 rounded-lg text-slate-300 text-[24px] font-bold border border-slate-600">有向图</div>
<div class="flex flex-col items-center gap-8">
<svg width="400" height="250" viewBox="0 0 400 250" class="overflow-visible">
<defs>
<marker id="arrow-strong-lg" markerWidth="12" markerHeight="12" refX="16" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#c084fc" />
</marker>
</defs>
<!-- Cycle Path: A->B->C->D->A -->
<path d="M100 50 L300 50" stroke="#c084fc" stroke-width="3" marker-end="url(#arrow-strong-lg)">
<animate attributeName="stroke-dasharray" from="0,1000" to="1000,0" dur="2s" fill="freeze"/>
</path>
<path d="M300 50 L300 200" stroke="#c084fc" stroke-width="3" marker-end="url(#arrow-strong-lg)"/>
<path d="M300 200 L100 200" stroke="#c084fc" stroke-width="3" marker-end="url(#arrow-strong-lg)"/>
<path d="M100 200 L100 50" stroke="#c084fc" stroke-width="3" marker-end="url(#arrow-strong-lg)"/>
<!-- Cross connections -->
<path d="M300 50 L100 200" stroke="#c084fc" stroke-width="3" marker-end="url(#arrow-strong-lg)"/>
<!-- Nodes -->
<g fill="#6b21a8" stroke="#c084fc" stroke-width="3">
<circle cx="100" cy="50" r="24"/>
<text x="100" y="58" text-anchor="middle" fill="#fff" font-size="20" stroke="none" font-weight="bold">A</text>
<circle cx="300" cy="50" r="24"/>
<text x="300" y="58" text-anchor="middle" fill="#fff" font-size="20" stroke="none" font-weight="bold">B</text>
<circle cx="300" cy="200" r="24"/>
<text x="300" y="208" text-anchor="middle" fill="#fff" font-size="20" stroke="none" font-weight="bold">C</text>
<circle cx="100" cy="200" r="24"/>
<text x="100" y="208" text-anchor="middle" fill="#fff" font-size="20" stroke="none" font-weight="bold">D</text>
</g>
</svg>
<div class="text-center bg-purple-900/20 px-8 py-4 rounded-xl border border-purple-500/30">
<p class="text-[32px] text-purple-400 font-bold mb-2">强连通图</p>
<div class="flex gap-8 text-[24px] text-slate-300 font-mono">
<span>A ↔ B</span>
<span>B ↔ C</span>
<span>...</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- P11: 总结 -->
<section class="slide" data-title="小结">
<h2>本节小结</h2>
<div class="flex items-center justify-center h-full">
<div class="card p-10 border-slate-700 bg-slate-800/30 w-2/3">
<ul class="space-y-6 text-[32px]">
<li class="flex items-center">
<span class="w-12 h-12 rounded-full bg-slate-700 flex items-center justify-center text-slate-200 text-xl font-bold mr-6">1</span>
<span>图是 <strong class="text-white">G = (V, E)</strong>,表示多对多关系。</span>
</li>
<li class="flex items-center">
<span class="w-12 h-12 rounded-full bg-slate-700 flex items-center justify-center text-slate-200 text-xl font-bold mr-6">2</span>
<span>边可以有 <strong class="text-white">方向 (Directed)</strong> 和 <strong class="text-white">权重 (Weight)</strong>。</span>
</li>
<li class="flex items-center">
<span class="w-12 h-12 rounded-full bg-slate-700 flex items-center justify-center text-slate-200 text-xl font-bold mr-6">3</span>
<span><strong class="text-white">度 (Degree)</strong> 是连接边的数量,有向图分入度和出度。</span>
</li>
<li class="flex items-center">
<span class="w-12 h-12 rounded-full bg-slate-700 flex items-center justify-center text-slate-200 text-xl font-bold mr-6">4</span>
<span><strong class="text-white">路径 (Path)</strong> 是顶点的序列,闭合的路径叫 <strong class="text-white">环 (Cycle)</strong>。</span>
</li>
<li class="flex items-center">
<span class="w-12 h-12 rounded-full bg-slate-700 flex items-center justify-center text-slate-200 text-xl font-bold mr-6">5</span>
<span><strong class="text-white">连通 (Connected)</strong> 指顶点间存在路径,有向图中有 <strong class="text-white">强连通</strong> 概念。</span>
</li>
</ul>
<div class="mt-12 text-center">
<p class="text-[28px] text-slate-500">Next : 图的存储 (邻接矩阵 & 邻接表)</p>
</div>
</div>
</div>
</section>
<!-- Page Number -->
<div id="page-number" class="absolute bottom-6 right-8 text-slate-500 text-[24px] font-mono z-50"></div>
</div>
<script>
let currentSlide = 0;
const pageNumberEl = document.getElementById('page-number');
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('page')) {
const page = parseInt(urlParams.get('page'));
if (!isNaN(page) && page > 0) currentSlide = page - 1;
}
function updateSlide() {
const slides = document.querySelectorAll('.slide');
if (currentSlide >= slides.length) currentSlide = slides.length - 1;
if (currentSlide < 0) currentSlide = 0;
slides.forEach((slide, index) => {
slide.classList.remove('active');
if (index === currentSlide) slide.classList.add('active');
});
if(pageNumberEl) pageNumberEl.textContent = `${currentSlide + 1} / ${slides.length}`;
try {
const url = new URL(window.location.href);
url.searchParams.set('page', currentSlide + 1);
window.history.replaceState(null, '', url.href);
} catch (e) {}
}
function nextSlide() {
if (currentSlide < document.querySelectorAll('.slide').length - 1) {
currentSlide++;
updateSlide();
}
}
function prevSlide() {
if (currentSlide > 0) {
currentSlide--;
updateSlide();
}
}
function resizeApp() {
const app = document.getElementById('app');
const scale = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
app.style.transform = `scale(${scale})`;
}
window.addEventListener('resize', resizeApp);
window.addEventListener('load', () => {
resizeApp();
updateSlide();
});
document.addEventListener('keydown', (e) => {
if (['ArrowRight', ' ', 'Enter'].includes(e.key)) nextSlide();
else if (e.key === 'ArrowLeft') prevSlide();
});
</script>
</body>
</html>