Seperti yang Yuval katakan, struktur datanya penting di sini. Saya akan mencoba memberikan solusi untuk beberapa jenis daftar adjacency:
- Daftar tepi masuk : Untuk setiap node, ada daftar simpul dari mana ada tepi masuk ke node ini. Anda cukup memindai semua simpul dan memeriksa apakah ukuran daftar kedekatan mereka0 atau tidak. Ukuran0daftar berarti tidak ada tepi yang masuk, sehingga simpul merupakan sumber atau terputus. Dengan asumsi grafik terhubung, pemindaian setiap titik ini akan memberi Anda daftar semua sumber (atau Anda dapat berhenti setelah menemukan satu) diO ( | V| )waktu - linear dalam jumlah simpul .
- Daftar tepi keluar : Untuk setiap node, ada daftar simpul yang ada tepi diarahkan dari node ini. Pertahankan bit-string dengan masing-masing bit mewakili sebuah vertex, diinisialisasi ke 0. Mulai dari node pertama, mulai memindai daftar untuk simpul yang ada tepi keluar dari ini. Setiap node seperti itu (tetangga) tidak bisa menjadi sumber, jadi terus atur bit terkait mereka dalam bit-string. Pada akhirnya, semua simpul yang bit terkaitnya masih belum disetel, adalah simpul sumber. Anda dapat melakukan ini dalam waktu linier dalam ukuran grafik -O ( | V| + | E| ).
- Kedua daftar bersama-sama : Untuk setiap simpul, ada daftar simpul campuran yang memiliki tepi ke atau dari simpul ini, dengan beberapa atribut lain yang menunjukkan yang mana dari keduanya sebenarnya adalah kasus. Pendekatannya mirip dengan 2 di atas, dengan tambahan bahwa setiap tepi yang masuk segera mengesampingkan simpul saat ini (dan Anda dapat menandai bit set-nya). Tidak seperti pada poin 2 di mana Anda harus melalui semua simpul, di sini, Anda mungkin menemukan beberapa sumber lebih cepat. Jika Anda tidak berhenti, Anda akan memiliki semua sumber. Untuk kedua kasus, waktu kembali linier dalam ukuran grafik -O ( | V| + | E| ).
- Kedua daftar secara terpisah : Cukup pilih daftar tepi yang masuk dan ikuti 1.
Sebagai catatan tambahan, jika memilih struktur data ada di tangan Anda, Anda mungkin ingin menganalisis semua operasi yang ingin Anda lakukan, dan seberapa sering, dan memilih struktur data yang sesuai.
Sunting: Untuk kasus 1, jika Anda memiliki dag di mana jumlah sumber sangat kecil dibandingkan dengan| V|(misalnya, dalam pohon dengan satu sumber), dan di mana jarak rata-rata dari titik mana pun ke sumber kecil dibandingkan dengan| V| dan Anda hanya menginginkan satu sumber saja, Anda dapat menggunakan algoritme rata-rata yang lebih cepat (meskipun kompleksitas asimptotik kasus terburuk akan sama). Pilih sembarang titik secara acak, dan buka salah satu induknya (dari daftar tepi yang masuk), dan terus ke induknya dan seterusnya, hingga Anda mencapai simpul yang tidak memiliki induk - sumber. Keuntungan kecil dari efisiensi ini adalah untuk jenis grafik yang sangat terbatas dengan algoritma yang sedikit lebih kompleks.