Tehtävien deadline: su-ma yö 25.4. 1:59.
Viikon aiheena on lyhimmät polut painotetuissa verkoissa. Tarvittavia algoritmeja ovat mm. Dijkstran algoritmi ja Floyd-Warshall. Lyhyt opas Dijkstran toteuttamisesta käytännössä. Ohessa on vielä video, jossa selitetään Dijkstran algoritmi leveyshaun laajennoksena.
Sinulle on annettu tieverkosto, ja tehtäväsi on etsiä lyhimmän reitin pituus kaikkien kaupunkiparien välillä. Jokaista kahta kaupunkia yhdistää yksi suora tie.
Toteuta seuraava metodi:
long[][] lyhinReitti(int n, long[][] et)
Parametri n
on kaupunkien määrä.
Se on kokonaisluku välillä 1..100.
Kaupungit on numeroitu tuttuun tapaan
kokonaisluvuin 1..n
.
Tieverkosto on annettu vierusmatriisiesityksessä. Luku et[i][j]
kertoo kaupunkeja i
ja j
yhdistävän tien pituuden. Verkosto on suuntaamaton painotettu verkko, eli et[i][j]=et[j][i]
. Kaikilla i
=1..n
pätee et[i][i]=0
.
Algoritmisi palauttaman taulukon kaksiulotteisen taulukon lyhin
, tulee olla yhtä suuri kuin syötteenä annettu taulukko et
. Luvun lyhin[i][j]
, missä i,j
ovat välillä 1..n
, pitää kertoa lyhimmän polun i -> j
pituus.
Jos syötteenä annettu matriisi on
long[][] et1={{0,0,0,0,0}, {0,0,9,1,2}, {0,9,0,3,1}, {0,1,3,0,7}, {0,2,1,7,0}};niin vastausmatriisin tulisi olla
long[][] v1= {{0,0,0,0,0}, {0,0,3,1,2}, {0,3,0,3,1}, {0,1,3,0,3}, {0,2,1,3,0}};
Sinulle on annettu tieverkosto, ja tehtäväsi on etsiä lyhin reitti kahden kaupungin välillä.
Toteuta seuraava metodi:
long lyhinReitti(int n, int[] mista, int[] minne, long[] matka)
Parametri n
on kaupunkien määrä.
Se on kokonaisluku välillä 1..105.
Kaupungit on numeroitu tuttuun tapaan
kokonaisluvuin 1..n
.
Taulukot mista
, minne
ja matka
kuvaavat kaupunkien väliset tiet.
Kaikki taulukot ovat samankokoisia,
ja teiden määrä on välillä 1..105.
Taulukko mista
kertoo,
mistä kaupungista tie alkaa,
taulukko minne
kertoo,
mihin kaupunkiin tie johtaa, ja
taulukko matka
kertoo
tien pituuden.
Kaikki tiet ovat kaksisuuntaisia,
ja jokaisen tien pituus on kokonaisluku välillä 1..109.
Metodin tulee palauttaa lyhimmän reitin pituus
kaupungista 1 kaupunkiin n
.
Jos mitään reittiä ei ole olemassa,
metodin tulee palauttaa -1.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | lyhinReitti(3, new int[] {1, 2}, new int[] {2, 3}, new int[] {5, 3}) | 8 |
2 | lyhinReitti(3, new int[] {1, 1}, new int[] {2, 3}, new int[] {2, 3}) | 3 |
3 | lyhinReitti(3, new int[] {1, 2, 1}, new int[] {3, 3, 2}, new int[] {9, 1, 1}) | 2 |
4 | lyhinReitti(3, new int[] {1, 2, 1}, new int[] {3, 3, 2}, new int[] {1, 9, 9}) | 1 |
Sinulle on annettu tiedot juna- ja lentoyhteyksistä. Haluaisit matkustaa kaupungista toiseen niin, että matkan varrella on mahdollisimman vähän lentoja.
Oletetaan esimerkiksi, että kaupunkeja on 3. Kaupungista 1 pääsee junalla kaupunkiin 2. Lisäksi kaupungista 1 pääsee lentäen kaupunkiin 2 ja kaupungista 2 pääsee lentäen kaupunkiin 3. Kun haluat matkustaa kaupungista 1 kaupunkiin 3, pienin mahdollinen määrä lentoja on 1: kaupungista 2 on pakko lentää kaupunkiin 3, koska kaupunkiin 3 ei pääse muulla tavalla.
Toteuta seuraava metodi:
int lentomaara(int n, int[] juna1, int[] juna2, int[] lento1, int[] lento2)
Parametri n
on kaupunkien määrä.
Se on kokonaisluku välillä 1..105.
Kaupungit on numeroitu tuttuun tapaan kokonaisluvuin
1..n
.
Taulukot juna1
ja juna2
kuvaavat junayhteydet.
Taulukossa juna1
lukee,
mistä kaupungista juna lähtee,
ja taulukossa juna2
lukee,
mihin kaupunkiin juna saapuu.
Kaikki yhteydet ovat kaksisuuntaisia.
Taulukot lento1
ja lento2
kuvaavat lentoyhteydet.
Taulukossa lento1
lukee,
mistä kaupungista lento lähtee,
ja taulukossa lento2
lukee,
mihin kaupunkiin lento saapuu.
Kaikki yhteydet ovat kaksisuuntaisia.
Sekä junia että lentoja on välillä 0..105.
Metodin tulee palauttaa pienin lentojen määrä,
jolla pääset kaupungista 1 kaupunkiin n
.
Jos mitään reittiä ei ole olemassa,
metodin tulee palauttaa -1.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | lentomaara(3, new int[] {1}, new int[] {2}, new int[] {1, 2}, new int[] {2, 3}) | 1 |
2 | lentomaara(3, new int[] {1}, new int[] {3}, new int[] {1, 2}, new int[] {2, 3}) | 0 |
3 | lentomaara(3, new int[] {}, new int[] {}, new int[] {1, 2}, new int[] {2, 3}) | 2 |
4 | lentomaara(3, new int[] {1, 2}, new int[] {2, 3}, new int[] {1, 2}, new int[] {2, 3}) | 0 |
Kyberhyökkäys on kaatanut suomen tietoverkot, mikä estää pääsysi iltasanomien nettisivuille. Verkkoa korjataan yhteys kerrallaan, kunnes kaikki yhteydet on saatu korjattua. Tehtävänäsi on selvittää, mihin aikaan saat taas yhteyden suosikkiuutissivustoosi.
Toteuta seuraava metodi:
long yhteysaika(int n, int[] mista, int[] minne, long[] milloin)
Parametri n
on verkon koneiden määrä.
Se on kokonaisluku välillä 1..105.
Koneet on numeroitu tuttuun tapaan kokonaisluvuin
1..n
. Sinun koneesi on kone numero 1 ja iltasanomien nettisivu löytyy koneelta numero n
.
Taulukot mista
, minne
ja milloin
kuvaavat tietoverkon korjaustöiden etenemistä. Tiedot ovat muotoa "ajanhetkellä milloin[i]
muodostuu koneiden mista[i]
ja minne[i]
välille yhteys". Kaikki yhteydet ovat kaksisuuntaisia! Näiden taulukoiden pituus on korkeintaan 105. Taulukon milloin
sisältämät luvut ovat välillä 1..1018.
Metodisi tulee palauttaa pienin ajanhetki, jolloin tietoverkossa on tarpeeksi korjattuja yhteyksiä, jotta yhteyden muodostaminen koneesta 1 koneeseen n
on mahdollista. Voit olettaa, että tämä on aina mahdollista, kunhan kaikki yhteydet on korjattu.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | yhteysaika(4, new int[] {1,2,3}, new int[] {2,3,4}, new long[] {1,2,1}) | 2 |
2 | yhteysaika(4, new int[] {1,1,2,3}, new int[] {2,3,4,4}, new long[] {1,5,8,7}) | 7 |
3 | yhteysaika(5, new int[] {1,2,2,3,4}, new int[] {2,3,4,5,5}, new long[] {10,1,8,1,9}) | 10 |
4 | yhteysaika(5, new int[] {1,2,2,3,4}, new int[] {2,3,4,5,5}, new long[] {1,1,8,1,9}) | 1 |
Haluat matkustaa mahdollisimman halvalla Suomesta Australiaan, joten olet varautunut lentämään useaa lyhyempää lentoa käyttäen. Käytössäsi on lisäksi yksi alennuskuponki, jolla voit puolittaa yhden lennon hinnan (parittomalla hinnalla pyöristetään vielä alaspäin). Tehtävänäsi on selvittää, mikä on halvin hinta, jolla pääset Suomesta Australiaan.
Toteuta seuraava metodi:
long halvinReitti(int n, int[] mista, int[] minne, long[] hinta)
Parametrit kuvaavat lentokentät ja niiden väliset lennot samalla tavalla kuin aiemmissa tehtävissä. Kaikki lennot ovat yksisuuntaisia. Lentokenttien määrä on välillä 1..105 ja samoin lentojen määrä on välillä 1..105. Jokaisen lennon hinta on välllä 1..109.
Aloitat matkasi lentokentältä numero 1 ja kohteenasi on lentokenttä numero n
. Metodisi on palautettava halvimman mahdollisen lentoyhdistelmän hinta.
Tehtävän aikaraja on poikkeuksellisesti 2s.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | halvinReitti(3, new int[] {1,2,1,2}, new int[] {2,3,3,1}, new long[] {3,1,7,5}) | 2 |
2 | halvinReitti(4, new int[] {1,1,2,3}, new int[] {2,3,4,4}, new long[] {1,4,8,4}) | 5 |
3 | halvinReitti(4, new int[] {1,1,2,3}, new int[] {4,2,3,4}, new long[] {10,2,3,1}) | 4 |
4 | halvinReitti(4, new int[] {1,1,2,3}, new int[] {4,2,3,4}, new long[] {10,3,3,3}) | 5 |